如果你真的想做ucontext.h 函数允许的事情,我会继续使用它们。其他任何东西都将不那么便携。在 POSIX 中将它们标记为过时似乎是委员会成员犯的一个可怕的迂腐错误。 POSIX 本身要求函数指针和数据指针大小相同,并且函数指针可以表示为void *,而 C 本身需要在函数指针类型之间进行类型转换并返回到往返安全,所以有很多方法这个问题本来可以解决的。
有一个真正的问题,除非可变参数和非可变参数函数的调用约定碰巧是一样的(即使那样,它是否可以稳健地完成也是相当值得怀疑的)。然而,这个问题可以简单地通过弃用 makecontext 以外的任何形式使用 makecontext(ucp, func, 1, (void *)arg); 来解决。
也许更好的问题是为什么您认为ucontext.h 函数是处理线程的最佳方式。如果您确实想使用它们,我可能会建议编写一个包装器接口,您可以使用ucontext.h 或 实现 either 与 pthreads,然后比较性能和膨胀。这还有一个好处,如果未来的系统放弃对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);
希望我没问题;至少总体思路是正确的。如果有人看到错误,请发表评论,以便我修复它。这种用法可能完全不需要一半的锁定(other_thread 的互斥锁),因此您可以将互斥锁设为task_switch 函数中的局部变量。您真正要做的就是使用pthread_cond_wait 和pthread_cond_signal 作为“进入睡眠”和“唤醒其他线程”原语。