Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如果在I';我在做有时间限制的等待?_C++_Boost_Timeout_Condition Variable_Time Wait - Fatal编程技术网

C++ 如果在I';我在做有时间限制的等待?

C++ 如果在I';我在做有时间限制的等待?,c++,boost,timeout,condition-variable,time-wait,C++,Boost,Timeout,Condition Variable,Time Wait,当对具有持续时间的boost::condition\u变量使用timed\u wait时,即使用户(或ntp)更改系统时间,等待条件是否会在持续时间后超时 例如: 如果您的流程也使用信号,我确实发现了一些问题。我还使用具有持续时间的Boost条件变量 我们有一个进程,它使用POSIX定时器来获得20赫兹的精确定时。当此计时器激活且时间设置为较早的日期/时间时,条件变量将阻塞。当我将时间更改回原始值时,条件变量将继续 我从Boost复制了实现,并将时钟模式设置为clock_MONOTONIC。现在

当对具有持续时间的
boost::condition\u变量使用
timed\u wait
时,即使用户(或ntp)更改系统时间,等待条件是否会在持续时间后超时

例如:


如果您的流程也使用信号,我确实发现了一些问题。我还使用具有持续时间的Boost条件变量

我们有一个进程,它使用POSIX定时器来获得20赫兹的精确定时。当此计时器激活且时间设置为较早的日期/时间时,条件变量将阻塞。当我将时间更改回原始值时,条件变量将继续

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


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

我相信这是一种竞争条件,尽管非常罕见。带有持续时间的condition_variable::timed_wait()的实现只是使用get_system_time()+wait_duration将值转换为系统时间。如果系统时间在调用get_system_time()的时间之间发生变化,并且计算的等待结束时间被重新转换为底层操作系统调用的基于刻度的计数器,则等待时间将是错误的

为了验证这个想法,我在Windows上编写了一个简单的程序,其中一个线程每100毫秒生成一个输出,如下所示:

for (;;)
{
    boost::this_thread::sleep( boost::get_system_time() +
        boost::posix_time::milliseconds( 100 ) );
    std::cout << "Ping!" << std::endl;
}
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::this_thread::sleep(boost::get_system_time()+
boost::posix_time::毫秒(100));
std::cout截至本文撰写之日(2013年11月),如果在等待升压条件变量时,挂钟时间发生变化,您只会得到不好的结果

如果您不必使用boost,可以使用所谓的“单调时钟”。由于单调时钟不受墙上时钟时间变化的影响,因此不会出现您描述的问题。您可以使用pthreads API使用以下方法安全地等待5秒:

for (;;)
{
    boost::this_thread::sleep( boost::get_system_time() +
        boost::posix_time::milliseconds( 100 ) );
    std::cout << "Ping!" << std::endl;
}
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::condition_变量的实现。也许有一天他们会解决这个问题。实现如下:

问题已在1.61版本中解决:


@Roddy:好的,但为了记录在案,你的答案与我当时的实验结果相符。该修复程序是在boost的1.60版中发布的:@SimonAlfie。你能告诉我该修复程序是否适用于windows操作系统吗?如果是,默认情况下是否有效,或者我需要先调用一些API吗?如果不是,我有什么选择吗?@swamy不确定该问题是否会受到影响是否所有平台。仅在Linux上报告(我怀疑它会影响所有平台)。为什么不尝试更新您的boost版本以查看它是否修复了它?无需先调用任何API。@SimonAlfie感谢您的回复。我能够在windows机器上签入v1.62。我正在使用
使用
稳定时钟
等待
API,当时间向前/向后更改时,等待的时间量是相同的。例如:如果我正在等待直到
12:00:30
并将时钟向前移动
5秒
,等待将在
12:00:35
到期。向后时间更改也同样适用。