Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.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++ 执行条件\u变量已正确计时\u等待_C++_Multithreading_Time - Fatal编程技术网

C++ 执行条件\u变量已正确计时\u等待

C++ 执行条件\u变量已正确计时\u等待,c++,multithreading,time,C++,Multithreading,Time,我正在阅读我的STL实现(标准版g++4.6.2),在condition\u变量中遇到了这一点竞争条件: template<typename _Rep, typename _Period> cv_status wait_for(unique_lock<mutex>& __lock, const chrono::duration<_Rep, _Period>& __rtime) { return wait_until(_

我正在阅读我的STL实现(标准版
g++4.6.2
),在
condition\u变量
中遇到了这一点竞争条件:

template<typename _Rep, typename _Period>
cv_status
wait_for(unique_lock<mutex>& __lock,
         const chrono::duration<_Rep, _Period>& __rtime)
{
    return wait_until(__lock, __clock_t::now() + __rtime);
}
事实上,底层pthreads实现似乎就是问题所在:

template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
{
    return timed_wait(m,get_system_time()+wait_duration);
}
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
   pthread_mutex_t *restrict mutex,
   const struct timespec *restrict abstime);
因为
abstime
被指定为“系统时间”,而不是单调的时钟

所以我的问题是:如何正确地实现像
std::condition\u variable::wait\u for
这样的东西?是否有一个现有的实现可以做到这一点?还是我遗漏了什么?

诀窍是使用a告诉
pthread\u condattr\t
使用
CLOCK\u monotic
。执行此操作的C代码非常简单:

#include <time.h>
#include <pthread.h>

#include <errno.h>
#include <stdio.h>

int main()
{
    // Set the clock to be CLOCK_MONOTONIC
    pthread_condattr_t attr;
    pthread_condattr_init(&attr);
    if (int err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
    {
        printf("Error setting clock: %d\n", err);
    }

    // Now we can initialize the pthreads objects with that condattr
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t  cond;
    pthread_cond_init(&cond, &attr);

    // when getting the time, we must poll from CLOCK_MONOTONIC
    struct timespec timeout;
    struct timespec now;
    clock_gettime(CLOCK_MONOTONIC, &now);
    timeout.tv_sec = now.tv_sec + 5;
    timeout.tv_nsec = now.tv_nsec;

    // business as usual...
    pthread_mutex_lock(&mutex);
    int rc = pthread_cond_timedwait(&cond, &mutex, &timeout);
    if (rc == ETIMEDOUT)
        printf("Success!\n");
    else
        printf("Got return that wasn't timeout: %d\n", rc);
    pthread_mutex_unlock(&mutex);

    return 0;
}
#包括
#包括
#包括
#包括
int main()
{
//将时钟设置为时钟单调
pthread_condattr_t attr;
pthread_condattr_init(&attr);
if(int err=pthread\u condattr\u setclock(&attr,CLOCK\u单调))
{
printf(“设置时钟时出错:%d\n”,错误);
}
//现在我们可以用condattr初始化pthreads对象
pthread\u mutex\u t mutex=pthread\u mutex\u初始值设定项;
pthread_cond_t cond;
pthread_cond_init(&cond,&attr);
//当我们得到时间时,我们必须从时钟开始投票
结构timespec超时;
现在构造timespec;
时钟获得时间(时钟单调,&现在);
timeout.tv_sec=now.tv_sec+5;
timeout.tv\u nsec=now.tv\u nsec;
//一切照旧。。。
pthread_mutex_lock(&mutex);
int rc=pthread\u cond\u timedwait(&cond,&mutex,&timeout);
if(rc==ETIMEDOUT)
printf(“成功!\n”);
其他的
printf(“得到了非超时的返回:%d\n”,rc);
pthread_mutex_unlock(&mutex);
返回0;
}

我将暂时不讨论这个问题,因为有人可能会有一个更简单的答案。我不满意的是,这意味着用实时时钟很难实现
等待
(我的最佳解决方案是将
时间点中提供的
时钟
转换为
稳定时钟
的时间,然后从那里开始……它仍然会受到时间更改竞争条件的影响,但如果你实时指定超时,你已经犯了一个可怕的错误).

注意:在内部,
pthread\u cond\u timedwait
使用
gettimeofday
,如果您想在指定的时间内超时,这是假的:您可能被迫使用其他使用单调时钟的计时器线程,然后在服务生取消之前唤醒服务生。如果我不得不这么做的话(我非常希望我不会这样做),我宁愿在我的
wait_for
函数中做一个旋转等待(看起来我的
sleep_for
没有这个问题,因为
nanosleep
没有同样的问题,因为它正确地使用了
时钟单调的
)。请注意。我怀疑是否有更简单的答案,因为这是POSIX API的一个限制。请注意,
condition\u variable
不仅存在定时等待问题,而且
mutex
也存在此问题。此外,对于mutex,情况更糟,因为没有
pthread\u mutextatr\u setclock
这样的API: .