相关疑难解决方法(0)

是否有任何表现良好的POSIX间隔定时器?

受到最后一个闰秒的启发,我一直在探索使用POSIX调用的计时(特别是间隔计时器).

POSIX提供了几种设置计时器的方法,但它们都有问题:

  • sleep并且nanosleep这些在被信号中断后重新启动很烦人,并引入了时钟偏差.您可以通过一些额外的工作来避免一些但不是全部的这种偏差,但这些功能使用实时时钟,所以这并非没有陷阱.
  • setitimer或者更现代的timer_settime这些被设计为间隔计时器,但它们是每个进程,如果您需要多个活动计时器,这是一个问题.它们也不能同步使用,但这不是什么大问题.
  • clock_gettime并且clock_nanosleep在使用时看起来像是正确的答案CLOCK_MONOTONIC.clock_nanosleep支持绝对超时,因此您可以只是睡眠,增加超时,然后重复.在中断之后也很容易重启.不幸的是,这些功能可能也是特定于Linux的:在Mac OS X或FreeBSD上不支持它们.
  • pthread_cond_timedwait可以在Mac上使用,可以gettimeofday作为一个kludgy解决方案,但在Mac上它只能与实时时钟一起使用,因此当系统时钟设置或闰秒发生时,它会受到不当行为的影响.

我缺少一个API吗?是否有一种合理的可移植方式在类UNIX系统上创建性能良好的间隔定时器,或者这总结了今天的状态?

通过良好的行为和合理的便携性,我的意思是:

  • 不容易出现时钟偏差(当然,减去系统时钟自身的偏差)
  • 适应正在设置的系统时钟或发生闰秒
  • 能够在同一个过程中支持多个计时器
  • 至少可在Linux,Mac OS X和FreeBSD上使用

关于闰秒的注释(响应R ..的回答):

POSIX天的长度恰好是86,400秒,但现实世界的日子很少会更长或更短.系统如何解决这种差异是由实现定义的,但闰秒通常与前一秒共享相同的UNIX时间戳.另请参见:闰秒以及如何处理它们.

Linux内核闰第二个错误是在将时钟设置为秒后无法进行内务处理的结果:https://lkml.org/lkml/2012/7/1/203.即使没有那个错误,时钟也会向后跳一秒钟.

c posix timer

18
推荐指数
2
解决办法
1万
查看次数

正确实现condition_variable timed_wait

我正在阅读我的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);
}
Run Code Online (Sandbox Code Playgroud)

因为__clock_t是一个std::chrono::system_clock,我们与NTP之类的东西有关(如果时钟在一天之后被移回__clock_t::now() + __rtime,那么我们将等待一天).

C++标准(30.5.1)看起来是正确的:

26

效果:好像

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);
}
Run Code Online (Sandbox Code Playgroud)

实际上,底层的pthreads实现似乎是问题所在:

int pthread_cond_timedwait(pthread_cond_t *restrict cond,
   pthread_mutex_t *restrict mutex,
   const struct timespec *restrict abstime);
Run Code Online (Sandbox Code Playgroud)

因为abstime被指定为"系统时间",而不是单调时钟.

所以我的问题是:如何才能std::condition_variable::wait_for正确实现?是否有现成的实现可以做到这一点?或者我错过了什么?

c++ time multithreading

12
推荐指数
1
解决办法
5469
查看次数

标签 统计

c ×1

c++ ×1

multithreading ×1

posix ×1

time ×1

timer ×1