Я запускаю следующий код на ОС Linux + процессор ARM + boost 1.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
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, необходимое для работы этого кода?
predicate
версию timed_wait. Возможно, это ложное пробуждение, заставляющее просыпаться рано.condition.timed_wait(lock, boost::posix_time::milliseconds(1000), f);
, гдеf
определяется какbool f(void) { return false; }
. - person Tsyvarev   schedule 29.07.2015futex
для ожидания по условию. Вы можете отследить вызовboost::xtime_get()
, посмотреть отметку времени, которую он возвращает, и сравнить ее с той, что была возвращенаclock_gettime
при вызовеcondition.timed_wait()
. - person Tsyvarev   schedule 30.07.2015