取消精确睡眠

Accurate Sleep with cancellation

本文关键字:取消      更新时间:2023-10-16

我需要实现准确且一致的延迟或睡眠功能,,必须能够取消

这是我的代码:

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中断。上面的功能可能会遇到由于重新安排和中断延迟而导致的时间误差的传播。

Windows Timestamp Project 描述了在计时器对象上等待的另一种技术。我的理解是,该技术无法提供取消手段(通过另一个主题,线程(。

问题:
1.如何改善线程延迟或睡眠的实现,这可以被另一个任务取消,并且更一致

  1. 可以终止睡眠的AFX线程吗?
    (当主线程终止睡眠AFX线程时会发生什么?(

  2. 当主线程终止称为waitforsingleobject的线程时,会发生什么?

准确性应大约为10ms,如10秒 10ms。
结果应在各种PC上保持一致(所有运行Windows 7或10(。

背景
有正确时机的PC正在运行Windows 7,以2.9 GHz运行。
时间不正确的PC运行Windows 7,以3.1 GHz运行,同时任务和应用程序运行较少。
应用程序是使用Visual Studio 2017和MFC框架(使用AFX进行线程创建(开发的。

您根本不应该实现。

在C 11中,标准中实现了所有用于多线程的必要实用程序。如果您不使用C 11-,则切换到C 11或更高 - 在不幸的情况下,请使用具有相同功能的Boost。

基本上,您想使用此功能的操作由std::condition_variable涵盖。您可以使用函数wait(它接受离开等待所需的条件函数(,wait_forwait_until(与wait相同,但总等待时间限制(以及notify_onenotify_all方法来唤醒睡眠的方法线程(一个或全部(,让他们检查觉醒状况并继续执行任务。

参考中查看std::conditional_variable。只需谷歌搜索它,您就会找到足够的信息。

如果您由于某种原因不信任std::conditional_variable实施,您仍然可以将其用于迷你等待和觉醒。

  • 我如何改善线程延迟或睡眠的实现, 可以被另一个任务取消,并且更一致?

    • 以前在这里讨论过高精度的睡眠。我使用了类似于此处描述的等待计时器方法。
  • 可以终止睡觉的AFX线程吗?(当主时会发生什么 线程终止睡觉的AFX线程?(

    • 我认为您是指用TerminateThread终止?AFX线程只是围绕标准Windows线程的包装器。他们没有什么特别的或神奇的,可以区分他们的行为。所以会发生的是一堆坏事:
      • 如果目标线程拥有关键部分,则关键部分将不会发布。
      • 如果目标线程正在从堆中分配内存,则不会释放堆锁。
      • 如果目标线程终止时执行某些内核32调用,则该线程过程的kernel32状态可能不一致。
      • 如果目标线程正在操纵共享DLL的全局状态,则可以破坏DLL的状态,从而影响DLL的其他用户。
    • 如果您可以访问应用程序的所有源代码,则不必这样做。
  • 主线程终止已调用的线程时会发生什么 WaitForSingleObject

    • 请参阅上一个子弹。CreateEventWaitForSingleObject实际上是终止线程的推荐方法。