假设我有以下代码:
#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跟踪器中是否有票?
提前致谢。
答案 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();
}
请注意,如果在程序退出之前未能加入线程,则无论如何行为都是未定义的。使用
表示工作完成。