【发布时间】:2015-08-03 14:25:24
【问题描述】:
我有一个应用程序需要在某些窗口中工作(在这种情况下,这些窗口都相隔 30 秒)。如果时间不在窗口内,则计算直到下一个窗口中间的时间,并且线程休眠该时间量(以毫秒为单位,使用boost::this_thread::sleep_for)。
使用 Boost 1.55,我能够在我的容差范围内(+/-100 毫秒)以极高的可靠性击中窗户。迁移到 Boost 1.58 后,我永远无法打开这些窗口。将boost::this_thread::sleep_for 替换为std::this_thread::sleep_for 可解决此问题;但是,我需要boost::thread 的可中断特性和boost::this_thread::sleep_for 提供的中断点。
下面是一些说明问题的示例代码:
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <chrono>
#include <iostream>
#include <thread>
void boostThreadFunction ()
{
std::cout << "Starting Boost thread" << std::endl;
for (int i = 0; i < 10; ++i)
{
auto sleep_time = boost::chrono::milliseconds {29000 + 100 * i};
auto mark = std::chrono::steady_clock::now ();
boost::this_thread::sleep_for (sleep_time);
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now () - mark);
std::cout << "Boost thread:" << std::endl;
std::cout << "\tSupposed to sleep for:\t" << sleep_time.count ()
<< " ms" << std::endl;
std::cout << "\tActually slept for:\t" << duration.count ()
<< " ms" << std::endl << std::endl;
}
}
void stdThreadFunction ()
{
std::cout << "Starting Std thread" << std::endl;
for (int i = 0; i < 10; ++i)
{
auto sleep_time = std::chrono::milliseconds {29000 + 100 * i};
auto mark = std::chrono::steady_clock::now ();
std::this_thread::sleep_for (sleep_time);
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now () - mark);
std::cout << "Std thread:" << std::endl;
std::cout << "\tSupposed to sleep for:\t" << sleep_time.count ()
<< " ms" << std::endl;
std::cout << "\tActually slept for:\t" << duration.count ()
<< " ms" << std::endl << std::endl;
}
}
int main ()
{
boost::thread boost_thread (&boostThreadFunction);
std::this_thread::sleep_for (std::chrono::seconds (10));
std::thread std_thread (&stdThreadFunction);
boost_thread.join ();
std_thread.join ();
return 0;
}
以下是引用 Boost 1.58 作为包含目录并在我的工作站(Windows 7 64 位)上运行时的输出:
Starting Boost thread
Starting Std thread
Boost thread:
Supposed to sleep for: 29000 ms
Actually slept for: 29690 ms
Std thread:
Supposed to sleep for: 29000 ms
Actually slept for: 29009 ms
Boost thread:
Supposed to sleep for: 29100 ms
Actually slept for: 29999 ms
Std thread:
Supposed to sleep for: 29100 ms
Actually slept for: 29111 ms
Boost thread:
Supposed to sleep for: 29200 ms
Actually slept for: 29990 ms
Std thread:
Supposed to sleep for: 29200 ms
Actually slept for: 29172 ms
Boost thread:
Supposed to sleep for: 29300 ms
Actually slept for: 30005 ms
Std thread:
Supposed to sleep for: 29300 ms
Actually slept for: 29339 ms
Boost thread:
Supposed to sleep for: 29400 ms
Actually slept for: 30003 ms
Std thread:
Supposed to sleep for: 29400 ms
Actually slept for: 29405 ms
Boost thread:
Supposed to sleep for: 29500 ms
Actually slept for: 29999 ms
Std thread:
Supposed to sleep for: 29500 ms
Actually slept for: 29472 ms
Boost thread:
Supposed to sleep for: 29600 ms
Actually slept for: 29999 ms
Std thread:
Supposed to sleep for: 29600 ms
Actually slept for: 29645 ms
Boost thread:
Supposed to sleep for: 29700 ms
Actually slept for: 29998 ms
Std thread:
Supposed to sleep for: 29700 ms
Actually slept for: 29706 ms
Boost thread:
Supposed to sleep for: 29800 ms
Actually slept for: 29998 ms
Std thread:
Supposed to sleep for: 29800 ms
Actually slept for: 29807 ms
Boost thread:
Supposed to sleep for: 29900 ms
Actually slept for: 30014 ms
Std thread:
Supposed to sleep for: 29900 ms
Actually slept for: 29915 ms
我希望std::thread 和boost::thread 的睡眠时间相同;然而,boost::thread 在被要求睡眠 29.1 - 29.9 秒时似乎想要睡眠约 30 秒。我是误用了boost::thread 接口,还是这是自 1.55 以来引入的错误?
【问题讨论】:
-
在大多数平台上,任何类型的线程睡眠功能都是“尽力而为”的交易;但如果它以前对你有用,它现在应该仍然有效......
-
我同意,很明显 std::thread 正在提供“尽力而为”的服务,因为它只精确到 +/- 30 毫秒(不计算测量计算所需的时间)。但是, boost::this_thread::sleep_for 提供的效果比“尽力而为”要差得多——它似乎将我的值四舍五入到 30 秒。
-
顺便说一句,在 Windows 8 上,您会再次看到与 Windows 7 大不相同的结果。我认为 Windows 10 会再次不同。
标签: c++ boost boost-thread