【问题标题】:Suspending and resuming threads in c++在 C++ 中暂停和恢复线程
【发布时间】:2011-08-08 21:14:30
【问题描述】:


我的应用程序必须每隔 *microsec*s 暂停和恢复一个不同的进程。
它工作正常,只是有时感觉它会暂停非统一时间的过程。
我使用 win API:ResumeThreadSuspendThread

另一方面,我尝试了一些不同的方法。
我像往常一样用SuspendThread 暂停了线程,但是当我恢复它时,我确实喜欢这样:

while (ResumeThread(threadHandle) > 0);

它的工作速度更快,并且以统一的速度运行其他进程。
为什么会这样?是否有可能有时线程被挂起两次,然后执行 ResumeThread 命令?
谢谢:)

【问题讨论】:

  • “是的,有可能”。您需要显示更多代码。
  • 如果您想自己进行调度,您可能希望使用光纤而不是线程(例如,请参阅 ConvertThreadToFiber:msdn.microsoft.com/en-us/library/ms682115.aspx)。
  • 我不能,这真的是很多代码。但理论上这可能是原因吗?我在哪里可以读到它?
  • 用三个字:“不要这样做!”。 SuspendThread 是难以跟踪的死锁的来源。改用适当的同步(例如命名信号量)。让其他进程blocksuspended
  • @Idov:请从更系统的角度添加更多关于实际残局目标的背景信息。您所写的内容表明存在一个重大的体系结构缺陷,其中最小的缺陷是试图将 Windows 用于实时任何事情。

标签: c++ windows resume suspend


【解决方案1】:

SuspendThread() 调用不会立即挂起线程。保存执行上下文需要一些时间,以便在线程尚未挂起时可能会调用ResumeThread()。这就是while (ResumeThread(threadHandle) > 0); 起作用的原因。要确定当前线程状态,您可以调用 NtQueryInformationThread(),但仅限于 NT 版本的 Windows。

如果辅助线程中有循环,您可以使用手动重置事件更改同步。主线程应该调用ResetEvent() 来挂起一个线程,并调用SetEvent() 来恢复。每个循环的辅助线程都应该调用WaitForSingleObjectEx()

【讨论】:

  • so "while (ResumeThread(threadHandle) > 0);"之所以有效,是因为“SuspendThread”可以在“ResumeThread”执行之前连续执行两次,然后暂停计数太高而无法通过一次调用“ResumeThread”来释放?
  • 我了解到您对 SuspendThread 和 ResumeThread 进行了配对调用。如果不是 - 您必须调用 ResumeThread 的次数与调用 SuspendThread 的次数一样多,因为每个线程都有一个“挂起计数器”。
  • 我确实成对调用它们,所以我确实需要使用“while (ResumeThread(threadHandle) > 0);”?
【解决方案2】:

我遵循了 Damon 的建议,从代码中删除了暂停/恢复,而是使用了一个同步对象,我的池线程在完成工作后无限等待,并且我的服务器线程在分配工作后发出相同的信号。

我现在唯一必须使用挂起的时间是当我第一次创建线程并为它分配工作后,线程从我的服务器线程恢复。创建的线程在线程池中反复使用以完成某些工作。

它就像一个魅力。

谢谢达蒙!

问候,

阿杰

【讨论】:

    【解决方案3】:

    这就是循环的样子

    for(i=0;i<num;i++) {     
      while (ResumeThread(threadHandle) > 0);
      ResumeThread(threadHandle)
      SuspendThread(threadHandle);      
    }
    

    SuspendThread 需要几毫秒,所以 while 循环一直持续到线程被挂起,然后再次调用线程进程 SuspendThread 函数,这是调用 GetProcessContext 以查看 EIP 的好方法

    【讨论】:

      猜你喜欢
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 2010-11-06
      • 1970-01-01
      • 2010-12-28
      相关资源
      最近更新 更多