boost - timed_wait does not wait
我正在Linux OS ARM处理器boost 1.51上运行以下代码。但是,代码无法按预期工作,并且timed_wait()调用立即返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <boost/thread/condition.hpp> #include <boost/thread/xtime.hpp> #include <boost/thread/mutex.hpp> #include <iostream> using namespace std; int main() { boost::mutex mutex_; boost::mutex::scoped_lock lock( mutex_ ); boost::xtime xt; boost::condition condition; // wait for one second or wait on lock boost::xtime_get(&xt, boost::TIME_UTC_); xt.sec += 1; cout <<"Before 1 second wait" << endl; condition.timed_wait(lock, xt); cout <<"After 1 second wait" << endl; return 0; } |
在具有相同ARM处理器,但不同版本的Linux glibc具有相同boost 1.51库的其他系统上,代码可以正常工作并等待1秒钟。
我尝试使用strace调试问题。我看到在不起作用的系统中未调用futex()的区别。
运行代码的系统中的跟踪:
1 2 3 4 5 6 7 8 | write(1,"Before 1 second wait\ ", 21Before 1 second wait) = 21 futex(0xb6fbf0dc, FUTEX_WAKE_PRIVATE, 2147483647) = 0 clock_gettime(CLOCK_REALTIME, {1438150496, 732211544}) = 0 futex(0xbef07a44, FUTEX_WAIT_PRIVATE, 1, {0, 998193456}) = -1 ETIMEDOUT (Connection timed out) futex(0xbef07a28, FUTEX_WAKE_PRIVATE, 1) = 0 write(1,"After 1 second wait\ ", 20After 1 second wait) = 20 |
在代码不起作用的系统上的跟踪:
1 2 3 4 5 6 7 | write(1,"Before 1 second wait\ ", 21Before 1 second wait) = 21 futex(0xb6fc90dc, FUTEX_WAKE_PRIVATE, 2147483647) = 0 clock_gettime(CLOCK_REALTIME, {1438150407, 134963583}) = 0 futex(0xbe9be988, FUTEX_WAKE_PRIVATE, 1) = 0 write(1,"After 1 second wait\ ", 20After 1 second wait) = 20 |
要使此代码正常工作,是否需要更改内核/ glibc?
我可以通过将超时从1更改为100来了解发生了什么。
我将超时作为参数传递给程序,并使用了
1 | xt.sec += timeout; |
当超时超过26时,程序正在等待(超时-26)秒。换句话说,程序等待1秒:如果超时为27,则为2秒:如果超时为28,依此类推...
偏移量26来自of秒数。如果系统上的时区信息包含leap秒信息,那么我们将看到此问题。如果我将时区信息(/ etc / localtime)更改为指向没有leap秒信息的zoneinfo文件,则boost API可以正常工作。
为什么不使用超时来浪费时钟,为什么不使用实际超时呢?
1 | condition.timed_wait(lock,boost::posix_time::milliseconds(1000)) |
这可以防止各种奇怪的问题。