如何在Mac OS X上使用C实现协作轻量级线程?

时间:2010-08-28 23:32:38

标签: c multithreading macos

我正在尝试找到一个轻量级的协作线程解决方案来尝试实现一个actor模型。 据我所知,唯一的解决方案是setcontext / getcontext, 但Apple的功能已被弃用(?)。我为什么这么做而感到困惑;但是,我找到了替代品。

  • Pthreads不是一个选项,因为我需要合作模型而不是抢先模型来精确/手动控制上下文切换时序而无需昂贵的锁定。

- 编辑 -

避免pthreads的原因: 因为pthreads不合作/确定性且太昂贵。我需要游戏逻辑代码的actor模型,因此需要数千个执行上下文。硬件线程需要MB内存和费用来创建/销毁。并行性并不重要。实际上,我只需要并发执行许多功能。这可以通过许多分开的函数和某种对象模型来实现,但我的目标是减少这些开销。

如果我知道有问题,请纠正我。非常感谢。

3 个答案:

答案 0 :(得分:3)

明显的“轻量级”解决方案是避免复杂的嵌套调用,除了执行时间紧密限制的有限情况,然后为每个“线程”存储显式状态结构,并将主程序逻辑实现为状态机在大多数点可轻松悬浮/恢复。然后,您可以简单地将指针交换为“上下文切换”的状态结构。基本上,这种技术相当于保留所有重要的状态变量,包括状态结构中通常为局部变量的变量。

这是否值得,可能取决于你避免pthreads的原因。如果你的理由是可以移植到非POSIX系统,或者你真的需要确定性的程序流程,那么它可能是值得的。但是,如果您只是担心性能开销和内存同步问题,我认为您应该使用pthread并管理这些问题。如果您避免不必要的锁定,请使用细粒度锁,并最大限度地减少锁定时间,性能不会受到影响。

编辑:根据您在主要问题的评论中发布的更多详细信息,我认为我提出的解决方案是正确的。每个演员都应该有自己的上下文,您可以在其中存储演员的动作/思考/等的状态。你将拥有一个run_actor函数,它将获取一个actor上下文和一些“ticks”来提升actor的状态,以及一个run_all_actors函数,它将遍历一个活动actor列表并调用{每个具有指定滴答数的每个{1}}。

此外,请注意,此解决方案仍允许您使用实际线程来利用SMP /多核计算机。你只需在线程之间划分演员。如果一个参与者需要检查另一个上下文(例如,用于碰撞检测),则可能需要一定程度的锁定。

答案 1 :(得分:1)

我也正在研究这个问题,我遇到了GNU Pth(不要与Pthreads混淆)。见http://www.gnu.org/software/pth/

它旨在成为协作线程的便携式解决方案。它确实提到它是通过setcontext / getcontext实现的(如果可用的话(因此它可能不在Mac OSX上)。否则它说它使用longjmp / setjmp,但我不清楚它是如何工作的。

希望这对搜索此问题的任何人都有帮助。

答案 2 :(得分:0)

我发现setcontext/getcontext中实现了setcontext/getcontext所需的一些功能。

不幸的是,由于libunwind的弃用,不会在Mac OS X上编译库。无论如何Apple已经实现了自己的/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/include/libunwind.h /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/usr/include/libunwind.h /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/include/libunwind.h /Developer/SDKs/MacOSX10.6.sdk/usr/include/libunwind.h /Developer/SDKs/MacOSX10.7.sdk/usr/include/libunwind.h ,它与源代码级的GNU实现兼容。该库存在于Mac OS X 10.6,10.7和iOS上。 (我不知道iOS的确切版本)

此库未记录,但我可以从这些位置找到标题。

libunwind

头文件中有一条注释要转到GNU {{1}}站点进行文档处理。

我会赌图书馆。