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

Aqu*_*irl 1 c++ notifications multithreading yield

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

案件:

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

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

是否有可能线程 A 发出通知通知_one() 但即使线程 B 已准备就绪,线程 A 仍会再次被调度?

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

Hum*_*ago 5

yield并且notify_one是不相关的。

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

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

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

是否有可能线程 A 发出通知通知_one() 但即使线程 B 已准备就绪,线程 A 仍会再次被调度?

是的。使用 Mesa 语义,向等待线程发送信号只会解除其他线程的阻塞。当前线程可能会继续运行,直到它用完时间。使用 Hoare 语义,信令线程将立即切换到等待线程。然而,几乎所有条件的实现都使用 Mesa 语义。

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

“等效”意味着他们做同样的事情。事实并非如此。我想你的意思是问它们是否是免费的,或者它们是否属于同一个同步方案的一部分,答案是否定的,正如我上面所解释的。

如果我们notify_one()用来唤醒一个线程,我们还需要yield()

如果线程 A 刚刚唤醒了线程 C,nofity_one并且您希望尽快运行线程 C,则可以调用yield放弃线程 A 的剩余时间片。但是,操作系统不需要批准您的请求。并且可能在线程 C 之前安排了许多您无法控制的线程。