在multithreading应用程序中等待variables的最佳方法是什么?

我想为multithreading程序做如下的事情:

// wait for variable to become true but don't hog resources // then re-sync queues 

这是一个很好的解决scheme吗?

 while (!ready) { Thread.Sleep(250); // pause for 1/4 second; }; 

Solutions Collecting From Web of "在multithreading应用程序中等待variables的最佳方法是什么?"

不,这不是一个好的解决方案。 首先它可能睡得太久。 其次线程很容易进入锁步。 这里有几个链接到正确的同步技术的MSDN文章:

  • 条件变量
  • 活动

以下是使用boost的方法:

 boost::condition_variable condvar; boost::mutex mutex; bool finished1 = false; bool finished2 = false; void longComputation1() { { boost::lock_guard<boost::mutex> lock(mutex); finished1 = false; } // Perform long computation { boost::lock_guard<boost::mutex> lock(mutex); finished1 = true; } condvar.notify_one(); } void longComputation2() { { boost::lock_guard<boost::mutex> lock(mutex); finished2 = false; } // Perform long computation { boost::lock_guard<boost::mutex> lock(mutex); finished2 = true; } condvar.notify_one(); } void somefunction() { // Wait for long computations to finish without "spinning" boost::lock_guard<boost::mutex> lock(mutex); while(!finished1 && !finished2) { condvar.wait(lock); } // Computations are finished } 

为了简洁起见,我没有包含线程产生的代码。

boost::lock_guard使用RAII语言在锁定对象超出范围时自动解锁互斥锁。 在例外情况下防止死锁非常有用。

我发现条件变量比Microsoft的Event对象更少出错。 如果你使用boost.Thread,你将获得跨平台可用性的额外好处。

尝试使用事件 (内核对象),而不是简单的变量,并通过替换你的循环:

 WaitForSingleObject(hEventHandle, INFINITE); 

上面的代码将工作,也许在某些情况下适当。

你也可以看看关键部分或信号量 – 这将使你的应用程序阻塞,并等待资源变得可用,

你的线程抓住了互斥锁,做了一些工作,同时,主要方法也试图抓住相同的互斥锁,但不能。 当工作者线程退出时,它们释放互斥锁,并且主线程可以通过关键部分并继续。

首先,你需要声明你的'ready'变量至少是'volatile',否则这可能有令人讨厌的副作用。 其次,长时间睡觉重新评估病情只是一个好主意,如果可能需要的时间确实很长,比如说几分钟。

使用WinAPI的事件函数( CreateEvent, SetEvent(), WaitForSingleEvent() )是最好的方法。 当然,它会引入一些开销,但通常是没有问题的。

如果您想坚持使用您的解决方案,在再次入睡前循环并重复检查几次,可以提高某些情况下的性能。

原始的Win32 API有这样做的EVENT,这里是一个用法示例:

http://msdn.microsoft.com/en-us/library/ms686915(VS.85).aspx

但是,该API是面向C的,尤其是Windows。 如果你正在编写一个C ++程序,你可能会考虑使用类似于boost :: threads的方法来使你的代码更加独立于平台。

我发现一个警告是,Windows可以WaitForMultipleObjects ,因此一次等待几个事件(和其他句柄类)。 提升没有平行的AFAIK。

在已经提供的良好答案的基础上,假设随机分配您希望检测到的事件,您将浪费一半的睡眠时间。 125ms是电脑时代的永恒。

Win32事件句柄上的WaitForSingleObject允许你立即检测所需信号(取决于你的进程中的其他线程在做什么),而不是做冗余检查(在信号到达之前你必须执行多少不必要的循环?) ,一旦完成它的工作就提供设置线程调用SetEvent。 布尔是多余的,这是应该的。

当然这是C#,但是我发现这本书对于多线程开发非常有帮助。

http://www.albahari.com/threading/

一些信息不是语言特定的。