【问题标题】:How does the function pthread_yield work?函数 pthread_yield 是如何工作的?
【发布时间】:2021-03-30 12:31:33
【问题描述】:

我正在用 C 语言实现一个线程库,但我对 pthread_yield() 的含义感到困惑。我已经在终端中的man page 上进行了查找,但我并没有真正理解解释。谁能给我解释一下?

【问题讨论】:

  • 能否请您详细说明您理解有困难的部分?
  • 没有太多要理解的,它是一个无用的函数,不会给你任何可用的结果。它可用于对编写得非常糟糕的程序进行猴子补丁,使其看起来非常轻微比实际情况要少,从而更难诊断潜在问题以及调试和修复真正的问题。
  • 它在手册页上说 pthread_yield 导致调用线程放弃 CPU。这意味着什么?
  • 这是关于the Linux pthread_yield() man page 的重要说明:“pthread_yield() 旨在与实时调度策略一起使用(即SCHED_FIFOSCHED_RR)。@ 的使用987654327@ 带有非确定性调度策略(例如 SCHED_OTHER)未指定,很可能意味着您的应用程序设计已损坏。"
  • 换句话说,如果你想让一个线程停止运行以便其他线程可以做某事,你不应该使用pthread_yield() - 或sleep() 或类似的东西。您需要使用适当的同步对象,例如互斥锁、信号量和条件变量。

标签: c multithreading pthreads yield


【解决方案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 ();
}

当您实现线程库时,请注意上述pthread_yield() 的 GLIBC 源代码(2.31 版本)会导致不寻常的 pthread API 行为,可能是实现错误 因为它直接返回 sched_yield() 的结果。与大多数 Linux 系统调用一样,后者返回 -1 并在失败时设置 errno(即使手册指定它实际上永远不会错误返回)。因此,理论上,这使得 pthread_yield() 返回 -1 并设置 errno 以防出错,尽管 pthread API 通常在成功时返回 0 并且在出错时返回错误号(errno 不应设置)。因此,手册将返回值描述为:

返回值
成功时,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;
[...]
}

符合manual:

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

【讨论】:

    【解决方案2】:

    请注意,尽管有其名称,pthread_yield 并未标准化。 Its Linux manual page 这样说,例如:

    此调用是非标准的,但存在于其他几个系统中。请改用标准化的 sched_yield(2)。

    The specifications for sched_yield() 的写法与pthread_yield() 的写法大致相同,但是:

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

    这只是意味着调用该函数的线程允许其他线程和进程有机会运行,等待恢复,直到再次轮到它。在诸如 pthreads 之类的抢占式多任务系统中没有必要这样做——内核在没有任何此类帮助的情况下管理将 CPU 时间分配给线程和进程——但有时可能会出现特殊情况,它可以解决线程调度问题.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-18
      • 2015-11-08
      • 2017-05-21
      • 2011-04-24
      • 2017-12-08
      • 2020-09-19
      • 2018-06-15
      • 2012-03-22
      相关资源
      最近更新 更多