准确的睡眠并取消

时间:2019-05-17 22:53:23

标签: c++ multithreading windows-7 sleep afx

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

这是我的代码:

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.我该如何改善线程延迟或睡眠的实现,而该延迟或睡眠可以被其他任务取消,并且更一致

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

  2. 当主线程终止名为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创建线程)开发的。

2 个答案:

答案 0 :(得分:0)

您根本不应实施此操作。

在C ++ 11中,所有用于多线程的基本实用工具都在标准中实现。 如果您不使用C ++ 11-然后切换到C ++ 11或更高版本-不幸的是,您不能使用C ++ 11或更高版本,请使用具有相同功能的Boost

基本上,std::condition_variable涵盖了您希望使用此功能进行的操作。您可以使用函数wait(接受离开等待的必要条件函数),wait_forwait_until(与wait相同,将线程置于等待模式总等待时间限制)以及唤醒睡眠线程(一个或全部)并使它们检查唤醒条件并继续执行任务的notify_onenotify_all方法。

在参考文献中检出std::conditional_variable。只需在Google上搜索它,您就会通过示例找到足够的信息。

如果由于某种原因您不信任std::conditional_variable实现,您仍然可以将其用于小型等待和唤醒。

答案 1 :(得分:0)

  •   

    如何改善线程延迟或睡眠的实现,   可以被其他任务取消,是否更一致?

  •   

    正在休眠的AFX线程可以终止吗? (当主电源   线程终止正在休眠的AFX线程?)

    • 我认为您是说以TerminateThread结尾? AFX线程只是标准Windows线程的包装。没有什么特别的或不可思议的东西可以使他们的行为与众不同。所以会发生bunch of bad stuff
      • 如果目标线程拥有一个关键部分,则该关键部分将不会被释放。
      • 如果目标线程正在从堆中分配内存,则不会释放堆锁。
      • 如果目标线程在终止时正在执行某些kernel32调用,则该线程的进程的kernel32状态可能不一致。
      • 如果目标线程正在操纵共享DLL的全局状态,则DLL的状态可能会被破坏,从而影响DLL的其他用户。
    • 如果您可以访问应用程序的所有源代码,则永远不必这样做。
  •   

    当主线程终止已调用的线程时会发生什么   WaitForSingleObject