Tôi đã đọc qua thực hiện STL của tôi (chuẩn vấn đề g++ 4.6.2
) và đi qua bit này của tình trạng chủng tộc bên trong condition_variable
:Thực hiện timed_wait condition_variable đúng
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);
}
Vì __clock_t
là một std::chrono::system_clock
, chúng tôi gắn liền với whims của những thứ như NTP (nếu đồng hồ được di chuyển trở lại bởi một ngày sau khi __clock_t::now() + __rtime
, sau đó chúng tôi sẽ chờ đợi một ngày).
C++ chuẩn (30.5.1) dường như làm cho nó đúng:
Effects: như thể
return wait_until(lock, chrono::steady_clock::now() + rel_time);
thực hiện condition_variable
Boost vừa thể hiện cùng vấn đề:
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);
}
Trong thực tế, việc thực hiện pthreads tiềm ẩn có vẻ là vấn đề:
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
vì abstime
được quy định như "thời gian hệ thống," không phải là một đồng hồ đơn điệu.
Vì vậy, câu hỏi của tôi là: Làm thế nào để thực hiện một cái gì đó như std::condition_variable::wait_for
chính xác? Có triển khai hiện tại nào nhận được quyền này không? Hay tôi đang thiếu một cái gì đó?
Lưu ý: Trong nội bộ, 'pthread_cond_timedwait' sử dụng' gettimeofday', không có thật nếu bạn muốn hết giờ trong thời gian bạn chỉ định: http://sourceware.org/git/?p=glibc.git;a=blob; f = nptl/pthread_cond_timedwait.c; h = 7278ec45b0eb0b48be50fe832fcd17ae988dca27; hb = HEAD –
Có lẽ bạn buộc phải sử dụng một số bộ đếm thời gian khác sử dụng đồng hồ đơn điệu, và sau đó đánh thức người phục vụ nếu nó hết hạn trước khi người bồi bàn hủy bỏ. – jxh
Nếu tôi phải đi xa đến mức đó (điều mà tôi hết sức hy vọng là không), tôi chỉ muốn thực hiện một sự chờ đợi trong hàm 'wait_for' của mình (có vẻ như' sleep_for' của tôi không có vấn đề đó, vì 'nanosleep' không có cùng một vấn đề vì nó sử dụng đúng' CLOCK_MONOTONIC'). –