我需要实现准确且一致的延迟或睡眠功能,并且必须能够取消。
这是我的代码:
bool cancel_flag(false);
void My_Sleep(unsigned int duration)
{
static const size_t SLEEP_INTERVAL = 10U; // 10 milliseconds
while ((!cancel_flag) && (duration > SLEEP_INTERVAL))
{
Sleep(duration);
duration -= SLEEP_INTERVAL;
}
if ((!cancel_flag) && (duration > 0U))
{
Sleep(duration);
}
}
以上函数在工作线程中运行。主线程能够更改“ cancel_flag”的值,以中止(取消)睡眠。
在我的商店中,持续时间为10秒(10000毫秒)时,我们会得到不同的结果。一些PC的睡眠时间为10秒,其他PC的睡眠时间为16秒。
有关Sleep()函数的文章说,该函数绑定到Windows中断,并且在持续时间过去后,将重新安排线程的计划(可能不会立即运行)。由于重新调度和中断等待时间,上述功能可能会遇到时间误差的传播。
Windows Timestamp Project描述了另一种等待计时器对象的技术。我的理解是,该技术无法提供取消方法(通过另一个,主线程)。
问题:
1.我该如何改善线程延迟或睡眠的实现,而该延迟或睡眠可以被其他任务取消,并且更一致?
正在休眠的AFX线程可以终止吗?
(当主线程终止正在休眠的AFX线程时会发生什么?)
当主线程终止名为WaitForSingleObject的线程时会发生什么?
精度应在10毫秒左右,例如10秒+ 10毫秒。
在各种PC(所有运行Windows 7或10的PC)上,结果应保持一致。
背景
时序正确的PC正在2.9 GHz上运行Windows7。
时序不正确的PC在3.1 GHz上运行Windows 7,同时运行的任务和应用程序较少。
应用程序是使用Visual Studio 2017和MFC框架(使用AFX创建线程)开发的。
答案 0 :(得分:0)
您根本不应实施此操作。
在C ++ 11中,所有用于多线程的基本实用工具都在标准中实现。 如果您不使用C ++ 11-然后切换到C ++ 11或更高版本-不幸的是,您不能使用C ++ 11或更高版本,请使用具有相同功能的Boost。
基本上,std::condition_variable
涵盖了您希望使用此功能进行的操作。您可以使用函数wait
(接受离开等待的必要条件函数),wait_for
和wait_until
(与wait
相同,将线程置于等待模式总等待时间限制)以及唤醒睡眠线程(一个或全部)并使它们检查唤醒条件并继续执行任务的notify_one
和notify_all
方法。
在参考文献中检出std::conditional_variable
。只需在Google上搜索它,您就会通过示例找到足够的信息。
如果由于某种原因您不信任std::conditional_variable
实现,您仍然可以将其用于小型等待和唤醒。
答案 1 :(得分:0)
如何改善线程延迟或睡眠的实现, 可以被其他任务取消,是否更一致?
正在休眠的AFX线程可以终止吗? (当主电源 线程终止正在休眠的AFX线程?)
TerminateThread
结尾? AFX线程只是标准Windows线程的包装。没有什么特别的或不可思议的东西可以使他们的行为与众不同。所以会发生bunch of bad stuff:
当主线程终止已调用的线程时会发生什么
WaitForSingleObject
?
CreateEvent
和WaitForSingleObject
实际上是recommended way of cleanly terminating threads。