Boost线程和try_join_for每次都给出不同的输出

Fro*_*art 6 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";
  }
}
Run Code Online (Sandbox Code Playgroud)

每次启动该程序时,MSVC-12.0和boost 1.55都会为我提供不同的输出。例如,

str
Finished

str
Finished

str
Running
Run Code Online (Sandbox Code Playgroud)

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

为什么?我究竟做错了什么?这是Boost库中的错误吗?Boost Bug Tracker中是否有入场券?

提前致谢。

Com*_*sMS 5

您的程序只是竞速,最可能的原因是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;
}
Run Code Online (Sandbox Code Playgroud)

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

请注意,一般来说,此类时序相关代码很脆弱。即使超时以毫秒为单位,如果您在执行过程中的错误时刻被抢占,并且CPU上的负载很高,那么在极少数情况下,您可能会错过最后期限。因此,请务必始终谨慎选择截止日期,并且不要假设截止日期在所有可能的情况下都足够大。