如果我们使用 notify_one() 来唤醒线程,我们还需要 yield() - 在 C++ 中吗?

If we use notify_one() to wake a thread, do we still need yield() - in C++?

产量(): https://en.cppreference.com/w/cpp/thread/yield
notify_one(): http://www.cplusplus.com/reference/condition_variable/condition_variable/notify_one/

案例:

线程 A 应该完成它正在做的任何事情,然后唤醒线程 B 来完成它的工作。

我在线程A'运行()函数中写了一个notify_one()调用。

线程 A 发出 notify_one() 信号,但即使线程 B 已准备就绪,线程 A 仍会再次调度的情况是否可能?

notify_one() 和 yield() 是等价的吗?

两者是有区别的。在您的情况下,有可能您可以使用它们中的任何一个来达到相同的效果。 yield 更通用,notify_one 提供对程序流的更多控制。

yield: 放弃处理器以便 OS 可以安排 任何其他 线程。
notify_one:发出条件信号,以便等待此条件的线程之一可以恢复。

Thread A is supposed to finish whatever it is doing and then wake thread B to do its job.

notify_one 是正确的选择,其中一个线程等待条件,而另一个线程可以发出信号。

yieldnotify_one 无关。

yield 是进程请求(向 OS)放弃其当前时间片。下一次仍会安排线程。想象一下,一个进程被分配了 10ms。如果它在 5 毫秒后调用 yield,则 OS 可以 运行 另一个进程。下次轮到 运行 时,它仍然会得到完整的 10 毫秒。 OS 不必满足请求。

condition_variable::notify_onecondition_variable::wait结合使用。如果有任何线程在等待,notify_one 保证唤醒其中之一。如果没有线程在等待,notify_one 什么都不做。

注意条件变量,当调用wait时,必须使用1个保护共享状态的互斥量(条件),它正在等待另一个线程发出信号当条件为真时。

Is a case possible that thread A signals notify_one() but still thread A is scheduled again even though thread B is ready?

是的。使用 Mesa 语义,向等待线程发出信号只会解除对另一个线程的阻塞。当前线程可能会继续 运行ning 直到它 运行s 超时。使用 Hoare 语义,发信号的线程将立即切换到等待线程。但是,几乎所有条件的实现都使用 Mesa 语义。

Are notify_one() and yield() equivalent of each other?

"Equivalent" 表示他们做同样的事情。事实并非如此。我想你的意思是问它们是否是免费的,或者它们是否是同一同步方案的一部分,答案是否定的,正如我上面所解释的。

If we use notify_one() to wake a thread, do we still need yield()

如果线程A刚刚用nofity_one唤醒了线程C,而你希望尽快运行线程C,你可以调用yield放弃线程A的剩余部分时间片。但是,不需要 OS 来批准您的请求。并且可能有许多线程调度在您无法控制的线程 C 之前。