如何实现多个线程'只在一个线程中运行

时间:2011-03-23 09:50:05

标签: java c multithreading scala actor

最近我一直在想:他们如何只在一个线程中实现几个“线程”?

我的意思是,他们如何在一个线程中实现几个并行运行的代码?他们如何保存'线程'的状态,创建一个中断并将CPU传递给下一个?

我认为Scala-actors实现了这一点。但是如何?

这可以回答JVM或C,没关系。我真的很想学习它的理论。

6 个答案:

答案 0 :(得分:6)

我认为你在这里混淆了coroutinesgreen threads

Coroutines在准备好的时候放弃了控制,没有任何中断,所以关于中断的问题在这里是无关紧要的。 Scala actor被实现为协同程序。

绿色线程是由虚拟机实现的用户模式线程,不使用本机操作系统功能。显然,虚拟机可以将任何指令插入正在执行的代码中,以检查是否需要切换到另一个线程。

答案 1 :(得分:4)

使用actor很简单,而不是每个actor使用一个线程,而是使用相同的线程为多个actor执行消息。但是,如果actor执行阻塞调用或繁重的计算,则必须使用另一个线程来执行其他actor中的消息。

绿色线程是轻量级线程,可以在VM级别实现。绿色线程始终映射到一个或多个OS线程。 VM在用户空间中处理同步和线程切换,这可以显着减少开销。但是,绿色线程存在缺陷,例如IO调用可能导致线程阻塞,然后VM无法“重用”OS线程用于另一个绿色线程,而必须使用额外的OS线程。

另一种解决方案是使用在Scala编译器中实现的continuation。然后,在JVM字节码级别处理执行的中断和恢复,其中保存和恢复本地状态。不需要VM支持。

答案 2 :(得分:3)

你的意思是像Java中的ExecutorService或ScheduledExecutorService中的任务吗?

这些任务将添加到队列中并执行完成。当一个完成另一个开始。如果您有一个延迟循环,则可以使用重复的计划任务。它为每次迭代完成,并允许其他任务运行。

如果您想了解更多细节,可能会发现阅读有趣的代码。

答案 3 :(得分:2)

使用coroutines

答案 4 :(得分:2)

Akka library是一个非常好的actor模型实现。它有一个非常好的直接Java API(除了Scala之外)和the doc is pretty good

答案 5 :(得分:1)

这样做的一种方法是让用户代码中的线程包注册自己,以便从内核获得某种定时器中断。每当它收到这样的中断时,它就会告诉内核停止执行本身运行多个不同线程的所有内核线程。对于每个线程,定时器中断代码可以检查堆栈中的那些线程,在辅助位置记录重要信息(寄存器,堆栈指针,程序计数器等),然后加载存储的信息中的另一个模拟在该实际线程上运行的线程。然后它可以恢复运行模拟线程的内核线程。通过这种方式,您可以模拟在单个内核线程上运行的多个线程之间的上下文切换。

要实现锁定等功能,您可以在用户空间中本地跟踪所有锁定信息。每当模拟线程尝试获取锁时,您都可以检查线程是否可以成功获取锁。如果是这样,你只需给它锁。否则,您通过交换该真实线程上运行的模拟线程来模拟上下文切换,然后将模拟线程标记为阻塞,直到锁再次释放为止。

这只是一个开始 - 这里有很多其他细节(如果其中一个模拟线程试图阻塞I / O操作怎么办?你不能只阻止内核线程,因为这会阻止所有的模拟线程!),但这是这个想法的要点。