{@ 1}}中的用户线程函数已弃用,因为它们使用了弃用的C功能(use a function declaration with empty parentheses for an argument)。
是否有标准替代品?我不认为成熟的线程擅长实现协作线程。
答案 0 :(得分:17)
如果你真的想做ucontext.h
函数允许的内容,我会继续使用它们。其他任何东西都不那么便携了。在POSIX中将它们标记为过时似乎是委员会中某人迂腐的可怕错误。 POSIX本身要求函数指针和数据指针具有相同的大小,并且函数指针可以表示为void *
,而C本身需要在函数指针类型之间进行转换,并且返回是往返安全的,所以有这个问题可以通过很多方式解决。
有一个真正的问题,如果没有编译器的主要帮助,将传递给int argc, ...
的{{1}}转换为传递给函数的表单是不可能的,除非调用约定为variadic和non可变函数碰巧是相同的(即使这样,它是否可以强有力地完成也是相当可疑的)。然而,这个问题可以通过弃用makecontext
以外的任何形式使用makecontext
来解决。
或许更好的问题是为什么你认为makecontext(ucp, func, 1, (void *)arg);
函数是处理线程的最佳方法。如果您确实想要使用它们,我可能会建议您编写一个包装器接口,您可以使用ucontext.h
或使用pthread实现 ,然后比较性能和膨胀。这也有一个好处,如果未来的系统放弃对ucontext.h
的支持,你可以简单地切换到使用基于pthread的实现进行编译,一切都会起作用。 (到那时,膨胀可能不那么重要,多核/ SMP的好处可能会很大,并且希望pthread实现不那么臃肿。)
编辑(基于OP的请求):要使用pthread实现“协作线程”,您需要条件变量。这是一个体面的pthreads教程,其中包含使用它们的信息:
https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables
“将执行权交给线程X”的合作多任务原语将类似于:
ucontext.h
希望我能做得好;至少一般的想法是正确的。如果有人看到错误请评论,以便我可以解决它。锁定(self->flag = 0;
other_thread->flag = 1;
pthread_mutex_lock(other_thread->mutex);
pthread_cond_signal(other_thread->cond);
pthread_mutex_unlock(other_thread->mutex);
pthread_mutex_lock(self->mutex);
while (!self->flag)
pthread_cond_wait(self->cond, self->mutex);
pthread_mutex_unlock(self->mutex);
的互斥锁)的一半可能完全不需要这种用法,因此您可以将互斥锁作为other_thread
函数中的局部变量。所有你真正要做的就是使用task_switch
和pthread_cond_wait
作为“去睡觉”和“唤醒其他线程”原语。
答案 1 :(得分:10)
对于它的价值,有一个Boost.Context
库recently accepted,只需要合并到官方的Boost版本中。 Boost.Context
解决了与POSIX ucontext
系列相同的用例:低开销协作上下文切换。作者在性能问题上苦苦挣扎。
答案 2 :(得分:5)
不,没有标准替代品。
您的选项是
<ucontext.h>
,即使它们包含过时的C. 答案 3 :(得分:1)
公开集团基本规格问题6 IEEE Std 1003.1,2004版
仍然使用相同的弃用语法列出makecontext()和swapcontext()。我还没有看到更新的东西。