提升 - timed_wait 不等待
boost - timed_wait does not wait
我运行下面的代码在LinuxOS+ARM处理器+boost 1.51上。但是,代码没有按预期工作,timed_wait() 立即调用 returns。
#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
来自代码不工作的系统的 strace:
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 才能使此代码正常工作?
与其在使用超时时乱用时钟,不如使用实际的超时?
condition.timed_wait(lock,boost::posix_time::milliseconds(1000))
这可以防止各种奇怪的问题。
我能够通过将超时从 1 更改为 100 来弄清楚发生了什么。
我将超时作为参数传递给程序并使用
xt.sec += timeout;
当超时超过 26 时,程序正在等待 (timeout - 26) 秒。也就是说,程序等待1秒:如果timeout为27,2秒:如果timeout为28,以此类推...
偏移量26来自闰秒数。如果系统上的时区信息包含闰秒信息,那么,我们就会看到这个问题。如果我更改时区信息 (/etc/localtime) 以指向一个没有闰秒信息的区域信息文件,那么 boost API 可以正常工作。
我运行下面的代码在LinuxOS+ARM处理器+boost 1.51上。但是,代码没有按预期工作,timed_wait() 立即调用 returns。
#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
来自代码不工作的系统的 strace:
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 才能使此代码正常工作?
与其在使用超时时乱用时钟,不如使用实际的超时?
condition.timed_wait(lock,boost::posix_time::milliseconds(1000))
这可以防止各种奇怪的问题。
我能够通过将超时从 1 更改为 100 来弄清楚发生了什么。
我将超时作为参数传递给程序并使用
xt.sec += timeout;
当超时超过 26 时,程序正在等待 (timeout - 26) 秒。也就是说,程序等待1秒:如果timeout为27,2秒:如果timeout为28,以此类推...
偏移量26来自闰秒数。如果系统上的时区信息包含闰秒信息,那么,我们就会看到这个问题。如果我更改时区信息 (/etc/localtime) 以指向一个没有闰秒信息的区域信息文件,那么 boost API 可以正常工作。