ResumeThread有时不会唤醒线程

时间:2016-02-01 17:06:26

标签: c++ multithreading winapi visual-c++

我的C ++中有两个函数:一个用于挂起,一个用于恢复线程。 在某些情况下,我需要停止所有线程但是当前它没关系,但是当我必须恢复线程时,有时它不起作用,我不是没有原因。 见方法:

procedure TForm1.Button2Click(Sender: TObject);
var
  days : integer;
begin
  if(Edit2.Text <> '') then
    begin
      days:= StrToInt(Edit2.Text);
      DDate.Minus(days);
      Edit1.Text := DDate.GetDate;
    end
  else
    ShowMessage('The field is required');
end;

上面的代码有什么问题吗? 有没有办法强制线程唤醒? 提前谢谢。

1 个答案:

答案 0 :(得分:7)

您不能以这种方式使用SuspendThread / ResumeThread。正如docs所说:

  

此功能主要供调试器使用。 它不适用于线程同步。如果调用线程尝试获取挂起线程拥有的同步对象,则在拥有同步对象(如互斥锁或临界区)的线程上调用SuspendThread会导致死锁。为了避免这种情况,应用程序中不是调试器的线程应该通知另一个线程暂停自身。 目标线程 必须 设计用于监听此信号并做出适当的响应

主要问题是 - 线程暂停时基本上没什么可做的。如果线程持有你需要的锁,你将死锁等待它释放它。并且您无法知道该线程可能具有哪些锁,因为线程可以在任意点被劫持以通过库使用的许多机制来执行任意工作。

你永远不会让它发挥作用,无论你试图通过暂停线程来解决什么问题,你都应该解决其他一些明智的方法。

问题的规范答案,&#34;如何在同一进程中安全地从另一个线程暂停/恢复线程?&#34;是&#34;通过该线程的合作,使用线程支持的任何机制。如果没有该线程的合作,就无法安全地完成。&#34;

任何时候你觉得你需要&#34;到达&#34;从外面做一个线程做正确的事情,你应该退后一步,重新思考你的设计。线程应该已经被编码为做什么,而且只做你希望它做的事情。如果线程需要挂起,则应将其编码为暂停。如果你必须伸手去做它你想做的事情或不做你不想要的事情,那么你首先编写错误并应该修复它。流程中的所有线程都必须合作。