boost thread和try_join_for每次都给出不同的输出

时间:2014-04-10 14:49:12

标签: c++ boost boost-thread

假设我有以下代码:

#include <boost/chrono.hpp>
#include <boost/thread.hpp>

#include <iostream>

int main()
{
  boost::thread thd([]{ std::cout << "str \n"; });

  boost::this_thread::sleep_for(boost::chrono::seconds(3));

  if (thd.try_join_for(boost::chrono::nanoseconds(1)))
  {
    std::cout << "Finished \n";
  }
  else
  {
    std::cout << "Running \n";
  }
}

MSVC-12.0和boost 1.55每次启动此程序时都会给出不同的输出。例如,

str
Finished

str
Finished

str
Running

当我将boost :: chrono :: nanoseconds改为boost :: chrono :: microseconds时,输出看起来像预期的那样。

为什么呢?我究竟做错了什么?它是boost库中的一个错误吗?在提升bug跟踪器中是否有票?

提前致谢。

2 个答案:

答案 0 :(得分:4)

你的程序只是一场比赛,很可能是因为1纳秒非常短。

try_join_for是通过调用try_join_until来实现的,这个函数将尝试加入,直到达到某个时间点为止:

// I stripped some unrelated template stuff from the code
//  to make it more readable

bool try_join_for(const chrono::duration& rel_time)
{
  return try_join_until(chrono::steady_clock::now() + rel_time);
}

bool try_join_until(const chrono::time_point& t)
{
  system_clock::time_point     s_now = system_clock::now();
  bool joined= false;
  do {
    Clock::duration   d = ceil<nanoseconds>(t-Clock::now());
    if (d <= Clock::duration::zero())
        return false; // in case the Clock::time_point t is already reached
    // only here we attempt to join for the first time:
    joined = try_join_until(s_now + d);
  } while (! joined);
  return true;
}

现在问题是try_join_until将在尝试加入之前检查是否已达到所请求的time_point。如您所见,它需要执行另外两个对clock::now()的调用和一些计算,以将获得的值与用户给出的截止时间进行比较。在时钟跳过超过给定的1纳秒截止时间之前,这可能会也可能不会完成,从而导致输出的不可预测性。

请注意,通常这样的时序相关代码是脆弱的。即使超时大约为毫秒,如果在执行期间被抢占并且CPU负载很高,在极少数情况下可能会错过最后期限。因此,请务必仔细选择最后期限,并且不要假设在所有可能的情况下,截止日期都足够大。

答案 1 :(得分:0)

只是致电.join()有什么问题?如果你坚持要在加入之前检查:

#include <boost/chrono.hpp>
#include <boost/thread.hpp>

#include <iostream>

int main()
{
  boost::thread thd([]{ std::cout << "str\n"; });
  boost::this_thread::sleep_for(boost::chrono::seconds(3));

  if (thd.joinable())
      thd.join();
}

请注意,如果在程序退出之前未能加入线程,则无论如何行为都是未定义的。使用

  • 期货,
  • 条件变量或
  • 信号量
如果那是你想要监控的内容,

表示工作完成。