23

不推荐使用中的用户线程函数,<ucontext.h>因为它们使用了不推荐使用的 C 功能(它们使用带有空括号的函数声明作为参数)。

他们有标准的替代品吗?我不觉得成熟的线程擅长实现协作线程。

4

4 回答 4

18

如果你真的想做一些ucontext.h功能允许的事情,我会继续使用它们。其他任何东西都将不那么便携。在 POSIX 中将它们标记为过时似乎是委员会成员犯的一个可怕的迂腐错误。POSIX 本身要求函数指针和数据指针具有相同的大小,并且函数指针可以表示为void *,而 C 本身需要在函数指针类型之间进行类型转换并返回到往返安全,所以这个问题有很多方法可以已解决。

有一个真正的问题,除非可变参数和非可变参数函数的调用约定碰巧是相同的(即使那样,它还是int argc, ...相当makecontext是否可以稳健地完成值得怀疑)。然而,这个问题可以简单地通过弃用makecontextmakecontext(ucp, func, 1, (void *)arg);.

不过,也许更好的问题是为什么您认为ucontext.h函数是处理线程的最佳方式。如果您确实想使用它们,我可能会建议编写一个您可以使用或使用 pthreads 实现的包装器接口然后ucontext.h 比较性能和膨胀。这还有一个好处,如果未来的系统放弃对ucontext.h. (到那时,膨胀可能不那么重要,多核/SMP 的好处可能会很大,希望 pthread 实现不会那么膨胀。)

编辑(根据 OP 的要求):要使用 pthread 实现“协作线程”,您需要条件变量。这是一个不错的 pthreads 教程,其中包含有关使用它们的信息:

https://computing.llnl.gov/tutorials/pthreads/#ConditionVariables

您的“将执行移交给线程 X”的协作多任务处理原语将类似于:

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_waitandpthread_cond_signal作为“进入睡眠”和“唤醒其他线程”原语。

于 2010-11-28T21:29:37.797 回答
10

值得一提的是,有一个最近被接受Boost.Context的库,只需合并到官方 Boost 版本中即可。解决与 POSIX 系列相同的用例:低开销的协作上下文切换。作者一直在努力解决性能问题。Boost.Contextucontext

于 2012-04-05T17:03:10.523 回答
6

不,它们没有标准替代品。

你的选择是

  • 继续使用<ucontext.h>,即使它们包含过时的 C.
  • 切换到 pthread
  • 编写自己的共线程库
  • 使用现有的(并且可能不那么便携的)共线程库,例如http://swtch.com/libtask/,尽管许多此类库是在 ucontext.h 之上实现的
于 2010-11-28T21:06:48.733 回答
0

开放组基本规范第 6 期 IEEE Std 1003.1, 2004 版

仍然列出了具有相同已弃用语法的 makecontext() 和 swapcontext()。我没有看到任何更新的东西。

于 2010-11-28T21:09:41.610 回答