g++和clang++中的condition_variable出现虚假唤醒问题

5

请看以下代码:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

using namespace std;

int main() {
  mutex m;
  condition_variable c;

  bool fired = false;
  int i = 0;

  // This thread counts the times the condition_variable woke up.
  // If no spurious wakeups occur it should be close to 5.
  thread t([&]() {
    unique_lock<mutex> l(m);
    while (!fired) {
      c.wait_for(l, chrono::milliseconds(100));
      ++i;
    }
  });

  // Here we wait for 500ms, then signal the other thread to stop
  this_thread::sleep_for(chrono::milliseconds(500));
  {
    unique_lock<mutex> l(m);
    fired = true;
    c.notify_all();
    cout << i << endl;
  }
  t.join();
}

现在,当我使用clang++ -std=c++11 -pthread foo.cpp进行构建时,一切都很好,在我的机器上输出4。然而,当我使用g++ -std=c++11 -pthread foo.cpp进行构建时,每次都会得到非常大的输出结果,例如81513。我知道虚假唤醒的数量是未定义的,但我很惊讶它如此之高。
额外的信息:当我用简单的wait替换wait_for时,clang和g++都输出0
这是g++中的一个错误/特性吗?为什么它甚至与clang不同?我能让它表现得更合理吗?
还有:gcc版本为gcc version 4.7.3 (Debian 4.7.3-4)

一个好的了解是在clang情况下使用哪个标准库。顺便说一句,它在我的系统上与gcc 4.8.1运行良好(无法编译4.7.3)。跟踪所有线程可能会导致更多有用的信息。 - PlasmaHH
gcc(Ubuntu / Linaro 4.7.2-2ubuntu1)4.7.2表示:4 - user2249683
clang使用与g++相同的标准库,我在该系统上没有libc++。顺便说一下,这是一个Debian测试版。 - lucas clemente
就此而言,我的Apple LLVM版本是4.2(clang-425.0.28),我也得到了4,就像你的clang一样。 - WhozCraig
在 Coliru 上使用 G++-4.7.3 编译此程序时,输出结果为 "4",因此除了编译器版本之外,还有其他变量在起作用。 - Casey
1个回答

1
我成功地运行了g++-4.8,问题解决了。非常奇怪,似乎是g++-4.7.3的一个bug,尽管我无法在另一台机器上重现它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接