pthread_yield 函数的工作原理是什么?

3

我正在用C语言实现一个线程库,在理解pthread_yield()的含义方面遇到了困难。我已经在终端上查阅了man page,但是我并没有真正理解其中的解释。有人能给我讲解一下吗?


1
这个函数并没有太多需要理解的地方,它是一个无用的函数,不会给你任何有用的结果。它可以用来猴子补丁极其糟糕编写的程序,使它们看起来比实际上稍微好一点,从而更难诊断潜在问题、调试和修复真正的问题。 - EOF
它“暗示”几乎什么都没有。pthread_yield()的一个理智的实现将是int pthread_yield(){return 0;} - EOF
2
这是关于Linux pthread_yield()手册页面的重要说明:“pthread_yield()旨在与实时调度策略(即SCHED_FIFOSCHED_RR)一起使用。在非确定性调度策略(如SCHED_OTHER)中使用pthread_yield()是未指定的,并且很可能意味着您的应用程序设计存在问题。 - Andrew Henle
2
换句话说,如果你想让一个线程停止运行以便其他线程可以做一些事情,你不应该使用 pthread_yield() - 或者 sleep() 或任何类似的东西。你需要使用适当的同步对象,如互斥锁、信号量和条件变量。 - Andrew Henle
pthread_yield(实际是sched_yield)在使用SCHED_FIFO时并不是无用或毫无意义的函数。减少上下文切换的数量是使用SCHED_FIFOsched_yield的一个好处,当你有很多线程,它们(1)以非平凡的方式相互依赖,但是(2)可以轻松地看到它们何时需要等待其他线程,并且(3)始终有足够的工作要做,这样至少其中一些线程可以继续工作。在这种情况下,试图通过信号量等自己管理调度只会增加编程复杂性和运行时开销。 - Matt
显示剩余3条评论
2个回答

3
请注意,尽管其名称为pthread_yield,但它并未标准化。例如,Linux手册页中指出:

该调用是非标准的,但在其他几个系统上存在。请使用标准化的sched_yield(2)。

sched_yield()的规范采用与pthread_yield()类似的术语编写:

sched_yield()函数强制运行线程放弃处理器,直到再次成为其线程列表的头。它不带任何参数。

这意味着调用该函数的线程允许其他线程和进程有机会运行,等待恢复,直到轮到它再次运行。在像pthread设计的抢占式多任务系统中,这样做并不必要--内核管理分配CPU时间给线程和进程,无需任何此类帮助--但可能偶尔存在一些特殊情况,可以平滑处理线程调度问题。

1
在GLIBC中,pthread_yield只是调用了sched_yield()系统调用(参见库源代码中的nptl/pthread_yield.c):
/* With the 1-on-1 model we implement this function is equivalent to
   the 'sched_yield' function.  */
int
pthread_yield (void)
{
  return sched_yield ();
}

作为实现线程库的开发者,请注意上述GLIBC源代码(2.31版本)中pthread_yield()的行为不寻常,这可能是一个实现错误,因为它直接返回sched_yield()的结果。和大多数Linux系统调用一样,后者如果失败会返回-1并设置errno(即使手册指定它实际上永远不会返回错误)。因此,理论上,pthread_yield()在出现错误时应该返回-1并设置errno,尽管pthread API通常在成功时返回0,在出现错误时返回错误号码(errno不应该被设置)。因此,当手册描述返回值如下时,手册是错误的或至少未遵守GLIBC的实现:

返回值
成功时,pthread_yield()返回0;出错时,它返回一个错误号码。

期望的源代码可能类似于:

int
pthread_yield (void)
{
  return sched_yield() == -1 ? errno : 0;
}

例如,pthread_sigmask() 的编码如下:
int
pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
{
[...]
  return sigprocmask (how, newmask, oldmask) == -1 ? errno : 0;
[...]
}

这符合手册中所述的内容:

返回值
成功时,pthread_sigmask() 返回 0;出错时,返回一个错误码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接