如果我们使用notify_one()唤醒线程,是否仍然需要yield()-在C ++中?

时间:2018-09-28 07:05:24

标签: c++ multithreading notifications 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发出信号notify_one()但即使线程B准备就绪,线程A仍被重新调度了?

notify_one()和yield()彼此相等吗?

2 个答案:

答案 0 :(得分:3)

yieldnotify_one无关。

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

condition_variable::notify_onecondition_variable::wait结合使用。如果有任何线程在等待,则保证notify_one唤醒其中之一。如果没有等待的线程,则notify_one将不执行任何操作。

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

  

是否有可能线程A发出信号notify_one()但即使线程B准备就绪,线程A仍被重新调度了?

是的。使用Mesa语义,发信号通知正在等待的线程只会解除阻塞另一个线程。当前线程可能会继续运行,直到时间用完。使用Hoare语义,信令线程将立即切换到等待线程。但是,几乎所有条件实现都使用Mesa语义。

  

notify_one()和yield()彼此相等吗?

“等效”表示它们执行相同的操作。事实并非如此。我想您是想问一下它们是否是互补的,或者它们是否属于同一同步方案,而答案是否定的,就像我上面解释的那样。

  

如果我们使用notify_one()唤醒线程,是否还需要yield()

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

答案 1 :(得分:0)

两者之间有区别。在您的情况下,有可能您可以同时使用它们中的任何一个。 yield更通用,notify_one提供了对程序流的更多控制。

yield:放弃处理器,以便操作系统可以调度任何其他线程。
notify_one:发信号通知一个条件,以便等待该条件的线程之一可以恢复。

  

线程A应该完成所有操作,然后唤醒   线程B来完成其工作。

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