简体   繁体   中英

boost - timed_wait does not wait

I am running the following code on a Linux OS + ARM processor + boost 1.51. But, the code does not work as intended and the timed_wait() call returns immediately.

#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;
}

On other systems having the same ARM processor, but different version of Linux + glibc + same boost 1.51 libraries, the code works okay and waits for 1 second.

I tried to debug the issue using strace. I see a difference where the call to futex() is not made in the system where it is not working.

strace from a system where the code is working:

write(1, "Before 1 second wait\n", 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\n", 20After 1 second wait)   = 20

strace from a system where the code is NOT working:

    write(1, "Before 1 second wait\n", 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\n", 20After 1 second wait)   = 20

Is there a kernel / glibc change that is needed to get this code working?

Instead of mucking with clocks when using timeouts, why not use an actual timeout?

condition.timed_wait(lock,boost::posix_time::milliseconds(1000))

This prevents all sort of weird problems.

I was able to figure out what was happening by changing the timeouts from 1 to 100.

I passed in the timeout as an argument to the program and used

xt.sec += timeout;

When the timeout is above 26, the program was waiting for (timeout - 26) seconds. In other words, the program waits for 1 second: if timeout is 27, 2 seconds: if timeout is 28, and so on...

The offset 26 is coming from the number of leap seconds. If the timezone information on the system contains leap second information, then, we are seeing this issue. If I change the timezone info (/etc/localtime) to point to a zoneinfo file that does not have leap second information, then, boost API works correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM