我正在尝试找到一个轻量级的协作线程解决方案来尝试实现一个actor模型。 据我所知,唯一的解决方案是setcontext / getcontext, 但Apple的功能已被弃用(?)。我为什么这么做而感到困惑;但是,我找到了替代品。
- 编辑 -
避免pthreads的原因: 因为pthreads不合作/确定性且太昂贵。我需要游戏逻辑代码的actor模型,因此需要数千个执行上下文。硬件线程需要MB内存和费用来创建/销毁。并行性并不重要。实际上,我只需要并发执行许多功能。这可以通过许多分开的函数和某种对象模型来实现,但我的目标是减少这些开销。
如果我知道有问题,请纠正我。非常感谢。
答案 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}}站点进行文档处理。
我会赌图书馆。