有什么东西可以替换<ucontext.h>函数吗?

zne*_*eak 22 c posix user-thread

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

它们有标准替代品吗?我不认为成熟的线程擅长实现协作线程.

R..*_*R.. 17

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

有一个真正的问题,如果没有编译器的主要帮助,将int argc, ...传入的转换makecontext为传递给函数的形式是不可能的,除非变量和非可变函数的调用约定碰巧是相同的(甚至它是相当的)是否可以做得很有问题.然而,这个问题可以简单地通过弃用makecontext除以外的任何形式的使用来解决makecontext(ucp, func, 1, (void *)arg);.

或许更好的问题是为什么你认为ucontext.h函数是处理线程的最佳方法.如果你想和他们一起去,我可能会建议写一个包装接口,可以实现既用ucontext.h 或与并行线程,然后比较性能和膨胀.这也有一个好处,如果未来的系统不再支持ucontext.h,你可以简单地切换到使用基于pthread的实现进行编译,一切都会起作用.(到那时,膨胀可能不那么重要,多核/ 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);
Run Code Online (Sandbox Code Playgroud)

希望我能做到这一点; 至少一般的想法是正确的.如果有人看到错误请评论,以便我可以解决它.other_thread对于这种用法,锁定(的互斥锁)的一半可能完全没有必要,因此您可以将互斥锁作为task_switch函数中的局部变量.所有你真正要做的就是使用pthread_cond_wait和pthread_cond_signal"去睡觉"和"唤醒其他线程"原语.

  • 我正在寻找协作线程,这是 pthread 不做的。在协作线程/用户线程中,每个线程负责让其他线程运行。pthread 是由操作系统调度的,这使得实现协作线程变得很痛苦。 (2认同)
  • 我知道这是可能的(尽管感谢您的参考),但它比 getcontext/setcontext 提供的方便得多。 (2认同)

小智 10

对于它的价值,有一个最近被接受的Boost.Context库,只需要合并到官方的Boost版本中.解决与POSIX 系列相同的用例:低开销协作上下文切换.作者在性能问题上苦苦挣扎.Boost.Contextucontext


nos*_*nos 5

不,没有标准替代品.

你有选择

  • 继续使用,<ucontext.h>即使它们包含过时的C.
  • 切换到pthreads
  • 编写自己的共同线程库
  • 使用现有的(可能不那么便携的)共同线程库,例如http://swtch.com/libtask/,尽管许多这样的库是在ucontext.h之上实现的.

  • 我确实会说很多; 关注使用协同程序的人肯定关注性能,并且仅仅因为漂亮的设计而强制进行上下文切换对他们的情况无济于事 (4认同)