使用时 timed_waitboost::condition_variable 持续时间,即使用户(或NTP)更改系统时间,等待状态也会在持续时间之后超时吗?

例如,

boost::posix_time::time_duration wait_duration(0, 0, 1, 0);  // 1 sec
// ** System time jumps back 15 minutes here. **
if( !signal.timed_wait(lock, wait_duration) )
{
    // Does this condition happen 1 second later, or about 15 minutes later?
}
有帮助吗?

解决方案

截至写作日期(2013年11月),如果您在Boost条件变量上等待时墙上的时间会发生变化,那么您将获得不良结果。

如果你 必须使用Boost,您可以使用所谓的“单调时钟”。由于单调时钟不受墙壁锁定时间的变化影响,因此它不容易受到您描述的问题的影响。您可以使用pthreads api安全地等待5秒钟:

pthread_condattr_t attr;
pthread_cond_t cond;
struct timespec ts;

pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
pthread_cond_init(&cond, &attr);
pthread_condattr_destroy(&attr);
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_sec += 5;
pthreead_cond_timedwait(&cond, &mutex, &ts);

您可以检查boost :: procenty_variable的实现。也许他们有一天会解决。实施在这里: http://svn.boost.org/svn/boost/trunk/boost/thread/pthread/pthread/condition_varible.hpp

其他提示

我相信这是一种种族条件,尽管很少见。使用持续时间的条件_variable :: TIMED_WAIT()的实现只需使用get_system_time()+wait_duration将值转换为system_time。如果系统的时间在get_system_time()之间发生变化,并且将计算出的等待终止时间重新连接到基于基础OS调用的基于tick的计数器,则您的等待时间将是错误的。

为了测试这个想法,在Windows上,我编写了一个简单的程序,其中一个线程每100ms每100ms生成一些输出,例如:

for (;;)
{
    boost::this_thread::sleep( boost::get_system_time() +
        boost::posix_time::milliseconds( 100 ) );
    std::cout << "Ping!" << std::endl;
}

另一个线程是过去一分钟将系统时间返回每100ms(此线程使用OS级“ Sleep()”调用,以避免转换为系统时间):

for ( ;; )
{
    Sleep( 100 );
    SYSTEMTIME sysTime;
    GetSystemTime( &sysTime );
    FILETIME fileTime;
    SystemTimeToFileTime( &sysTime, /*out*/&fileTime );
    ULARGE_INTEGER fileTime64 = (ULARGE_INTEGER(fileTime.dwHighDateTime) << 32) |
        fileTime.dwLowDateTime;
    fileTime64 -= 10000000 * 60;   // one minute in the past
    fileTime.dwHighDateTime = (fileTime64>>32) & 0xFFFFFFFF;
    fileTime.dwLowDateTime = fileTime64 & 0xFFFFFFFF;
    FileTimeToSystemTime( &fileTime, /*out*/&sysTime );
    SetSystemTime( &sysTime );
}

第一个线程,尽管应该输出“ ping!”每100毫秒,锁定很快。

除非我缺少某些内容,否则Boost似乎没有提供任何避免此内部转换到系统时间的问题,而使应用程序容易受到外部更改的影响。

如果您的过程还使用信号,我确实看到了一些问题。我还使用持续时间的升压条件变量。

我们有一个使用POSIX计时器以20 Hz的准确计时的过程。当激活此计时器并将时间设置为较早的日期/时间时,条件变量块。当我将时间更改回原始值时,条件变量将继续。

我将实现从boost复制,并将时钟模式设置为clock_monotonic。现在,即使更改时间,条件变量也可以正常工作。

如果有可能将条件变量的模式设置为单调,那将是有帮助的,但这目前是不可能的。

问题定为1.61开发分支:

https://svn.boost.org/trac/boost/ticket/6377

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top