代码之家  ›  专栏  ›  技术社区  ›  Bob

boost-timed_wait不等待

  •  2
  • Bob  · 技术社区  · 11 年前

    我在LinuxOS+ARM处理器+boost1.51上运行以下代码。但是,代码没有按预期工作,timed_wait()调用立即返回。

    #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()。

    代码正在工作的系统的strace:

    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
    

    来自代码不工作的系统的扫射:

        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
    

    是否需要对内核/glibc进行更改才能使代码正常运行?

    2 回复  |  直到 11 年前
        1
  •  0
  •   Mark Jansen    11 年前

    在使用超时时,为什么不使用实际的超时来处理时钟呢?

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

    这可以防止各种奇怪的问题。

        2
  •  0
  •   Bob    11 年前

    通过将超时时间从1改为100,我能够弄清楚发生了什么。

    我将超时作为参数传递给程序,并使用

    xt.sec += timeout;
    

    当超时值超过26时,程序正在等待(超时值-26)秒。换句话说,程序等待1秒:如果超时为27,则等待2秒:如果超时是28,依此类推。。。

    偏移26来自闰秒数。如果系统上的时区信息包含闰秒信息,那么,我们看到了这个问题。如果我将时区信息(/etc/localtime)更改为指向一个没有闰秒信息的zoneinfo文件,那么boost API将正常工作。