如果日期在2116年,则提升timed_wait不会等待
boost timed_wait doesn't wait if date is in 2116 year
示例:
boost::interprocess::interprocess_semaphore semDone(0);
long sec = 10;
boost::posix_time::ptime until = boost::posix_time::second_clock::universal_time() + boost::posix_time::seconds(sec);
bool ret = semDone.timed_wait(until);
它当时在Linux上工作得很好- timed_wait
等待10秒然后返回false
。
但是,如果我将系统日期移动到2116 year并重新运行应用程序,timed_wait
调用立即返回false
。boost的条件变量也有同样的问题。
信息:
- Linux sles12 3.12.39 x86_64 GNU/Linux
- g + + 4.8
- 增加1.54
time_t
的大小等于8。因此,建议使用64位time_t
而不是32位的答案不适用于问题。 让我试着用一个小的堆栈跟踪来描述发生问题的行(顺便说一句,我使用boost 1.58):
#0 boost::interprocess::ipcdetail::ptime_to_timespec (tm=...) at /usr/include/boost/interprocess/sync/posix/ptime_to_timespec.hpp:38
#1 0x402983 in boost::interprocess::ipcdetail::semaphore_timed_wait (handle=0x7fffffffe100, abs_time=...) at /usr/include/boost/interprocess/sync/posix/semaphore_wrapper.hpp:224
#2 0x402ab7 in boost::interprocess::ipcdetail::posix_semaphore::timed_wait (this=0x7fffffffe100, abs_time=...) at /usr/include/boost/interprocess/sync/posix/semaphore.hpp:55
#3 0x402b1d in boost::interprocess::interprocess_semaphore::timed_wait (this=0x7fffffffe100, abs_time=...) at /usr/include/boost/interprocess/sync/interprocess_semaphore.hpp:139
#4 0x40184d in main () at /tmp/t.cpp:10
好,让我们看看在方法ptime_to_timespec中发生了什么。您之前创建的ptime对象(第3行)
boost::posix_time::ptime until = boost::posix_time::second_clock::universal_time() + boost::posix_time::seconds(sec);
被传递给这个函数,并被转换成一个timespec对象。timespec对象在time.h中定义,可用于计算从1970年1月1日00:00:00开始的持续时间。(参见http://pubs.opengroup.org/onlinepubs/7908799/xsh/time.h.html)它包含像tv_sec(持续时间以秒为单位,类型为time_t), tv_nsec(类型为long)等成员。
问题很简单,以秒为单位的持续时间(从01/01/1970开始,以XX/XX/2116结束)太大,不适合tv_sec (time_t基本上是有符号整型)。这里也描述了这个问题:https://stackoverflow.com/a/471287/5967798
我用年份2116和函数返回的描述日期的timespec对它进行了测试9:18:59 am CET | Wednesday, October 8, 1980
问题的根本原因是boost::posix_time::time_duration::total_seconds()
显式地将返回值转换为time_resolution_traits::sec_type
,而在timed_wait()
调用期间通过boost::interprocess::ipcdetail::ptime_to_timespec()
将ptime
转换为timespec
。time_resolution_traits::sec_type
是对 int32_t
类型的类型定义(参见boost/date_time/time_resolution_files .hpp文件中的类型定义链)。
同时文档说time_duration::total_seconds()
返回 long
(http://www.boost.org/doc/libs/1_62_0/doc/html/date_time/posix_time.html)。但是对于LP64模型(例如Linux, 64位),它返回有符号32位整数,而不是long
(有符号64位整数)。
所以很明显在boost中有一个bug。该漏洞的第一张罚单出现在2009年。
门票:
- https://svn.boost.org/trac/boost/ticket/2819
- https://svn.boost.org/trac/boost/ticket/3109
- https://svn.boost.org/trac/boost/ticket/3487
- https://svn.boost.org/trac/boost/ticket/12214
我创建了一个新的:https://svn.boost.org/trac/boost/ticket/12609.
UPD:在Boost 1.66中修复了错误,在错误的注释中描述。
- std::condition_variable::wait()如何评估给定的谓词
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- std::memory_order for std::atomic:<T>:wait
- std::p romise::set_value() 和 std::future::wait() 是否提供内存围栏?
- 对于等待以 std::future wait() 返回的函数的 CPU 使用率或检查标志在循环中休眠一段时间哪个更好?
- std::future::get()或std::future::wait()是std::thread::join()的替
- 在 while 循环中使用 std::condition_variable::wait 是否正确
- future::wait() 是否与 async() 执行线程的完成同步?
- 为什么'wait with predicate'求解条件变量的'lost wakeup'?
- 线程锁定互斥锁的速度比 std::conditional_variable::wait() 快
- deadline_timer::wait 是否让位于其他任务
- std::future::wait 是内存障碍吗?(我无法解释这种数据竞赛)
- 如何退出 QThread::wait()
- 当Qtest :: Qwait(..)成功时,Qsignalspy :: Wait(..)失败
- 如何在Wait()C++期间同时调用另一个函数
- 在 Eclipse 中使用 GDB 时出错:"Command '-list-features' is timed out"
- 条件变量的"wait"函数在提供谓词时导致意外行为
- 在 UWP 应用程序中,future.wait() 在尝试同步来自异步方法的响应时继续等待
- 条件变量wait引发异常
- 为什么 future::wait() 块