gpt4 book ai didi

c++ - 正确实现 condition_variable timed_wait

转载 作者:IT老高 更新时间:2023-10-28 23:19:30 30 4
gpt4 key购买 nike

我正在阅读我的 STL 实现(标准问题 g++ 4.6.2)并在 condition_variable 中遇到了这种竞争条件:

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);
}

因为 __clock_t 是一个 std::chrono::system_clock,我们被 NTP 之类的奇思妙想所束缚(如果时钟在__clock_t::now() + __rtime,那我们就等一天)。

C++ 标准 (30.5.1) 似乎是正确的:

26

Effects: as if

return wait_until(lock, chrono::steady_clock::now() + rel_time);

Boost 的 condition_variable 实现也有同样的问题:

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);
}

其实底层的pthreads实现似乎是问题所在:

int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);

因为 abstime 被指定为“系统时间”,而不是单调时钟。

所以我的问题是:如何正确实现 std::condition_variable::wait_for 之类的东西?是否有现有的实现可以做到这一点?还是我错过了什么?

最佳答案

诀窍是使用 pthread_condattr_setclock 告诉pthread_condattr_t使用 CLOCK_MONOTONIC .执行此操作的 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;
}

我将暂时搁置这个问题,因为有人可能会有更简单的答案。我在这里不满意的是它意味着 wait_until使用实时时钟很难实现(我最好的解决方案是将 Clock 中提供的 time_point 转换为 steady_clock 的时间并从那里开始......它仍然受制于时间变化的竞争条件,但如果你实时指定超时,你已经犯了一个可怕的错误)。

关于c++ - 正确实现 condition_variable timed_wait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11893992/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com