使用信号处理程序和 setjmp/longjmp 实现抢占式微线程
我想在Linux环境中实现符合POSIX标准的微线程。基本思想如下:
- 使用此处描述的技术,分配新堆栈每根光纤的空间。
- 使用 setitimer,创建以恒定时间间隔发送信号的计时器。该定时器的信号处理程序将充当调度程序并在纤程之间进行切换。
问题是,在信号处理程序中执行 longjmp 不会终止处理程序,因此内核将等待其终止,而不是传递新信号。这使得切换上下文变得不可能,因为没有信号来启动切换。 一种解决方案是取消阻止 SIGALRM,这样许多信号可以同时执行处理程序,但这会导致竞争条件问题。
实现抢占式微线程的最佳和最简单的方法是什么?我在谷歌上找到的所有例子都不是先发制人的。
I want to implement POSIX compliant microthreads in Linux environment. Basic idea is as follows:
- Using technique described here, assign new stack space for each fiber.
- Using setitimer, create timer that will send signals in constant time interval. Signal handler for this timer will act as a scheduler and switch between fibers.
The problem is, that doing longjmp in signal handler, won't terminate the handler, so kernel will wait for it's termination, instead for delivering new signals. This makes switching contexts impossible, because there are no signals to initiate the switches.
One solution would be to unblock SIGALRM, so many signals can execute the handler at the same time, but this will cause race conditions problems.
What is the best and simplest way to implement preemptive microthreads ? All examples I found on Google were not preemptive.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决方案是使用 sigsetjmp / siglongjmp,而不是 setjmp/longjmp。 sig* 版本保留信号掩码:)
The solution is to use sigsetjmp / siglongjmp, intstead of setjmp/longjmp. sig* versions preserve signal masks :)