Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 多线程Delphi7应用程序-应用程序终止问题_Multithreading_Delphi_Synchronization_Delphi 7_Waitforsingleobject - Fatal编程技术网

Multithreading 多线程Delphi7应用程序-应用程序终止问题

Multithreading 多线程Delphi7应用程序-应用程序终止问题,multithreading,delphi,synchronization,delphi-7,waitforsingleobject,Multithreading,Delphi,Synchronization,Delphi 7,Waitforsingleobject,我有一个TThread的后代和一个对象列表,每个对象都有自己的线程副本,还有一个事件对象,是用CreateEvent()API创建的 不同的对象通过事件触发相互交互。即,每个线程必须等待其他线程触发其事件。当然,有一个“主”线程可以永久工作,所以自阻塞永远不会发生。这个系统在每个对象的Execute方法结束之前都工作得很好 当我试图中断所有线程(例如通过关闭应用程序)时,会出现问题。在这种情况下,我需要一些调用每个线程的Terminate方法的外部函数: for i := 0 to FLay

我有一个TThread的后代和一个对象列表,每个对象都有自己的线程副本,还有一个事件对象,是用CreateEvent()API创建的

不同的对象通过事件触发相互交互。即,每个线程必须等待其他线程触发其事件。当然,有一个“主”线程可以永久工作,所以自阻塞永远不会发生。这个系统在每个对象的Execute方法结束之前都工作得很好

当我试图中断所有线程(例如通过关闭应用程序)时,会出现问题。在这种情况下,我需要一些调用每个线程的Terminate方法的外部函数:

  for i := 0 to FLayers.Count - 1 do
  begin
    FLayers.Layer[i].FTerminating := true;
    f := true;
    while f do
    begin
      f := FLayers.Layer[i].IsActive;
      if f then
      begin
        Sleep(100);
        Application.ProcessMessages;
      end;
    end;
    FLayers.Layer[i].FTerminating := false;
  end;
此函数位于Form.OnClose()事件中

问题是大约有两个线程正常终止,但其他所有线程都在WaitForSingleObject()调用时停止:

procedure.thread.Execute;
开始
FLayer.FIsActive:=真;
...............
重复
//
如果终止或
剥皮机
(FLayer.FEvent=无效的句柄值)然后
开始
打破
结束;
//

Fres:=WaitForSingleObject(FLayer.FEvent,100) 与其使用WaitForSingleObject,不如使用WaitForMultipleObjects无限超时并等待两个事件,即FLayer.FEvent和第二个终止事件

AFAIR必须为每个进程创建一个终止事件。 如果WaitForMultipleObjects返回终止事件的ID,则退出循环


在OnClose()方法中,您必须简单地向所有终止事件发送信号。

而不是WaitForSingleObject您应该使用WaitForMultipleObjects无限超时并等待两个事件,即FLayer.FEvent和第二个终止事件

AFAIR必须为每个进程创建一个终止事件。 如果WaitForMultipleObjects返回终止事件的ID,则退出循环


在OnClose()方法中,您必须简单地向所有终止事件发送信号。

对不起,您是在谈论进程终止事件吗?请注意,我不关心进程终止。让我们把它当作一个程序来打断所有的线程。例如,我有“停止处理”菜单项,它不会关闭应用程序,但会中断所有线程,如上图所示。我不能无限期地等待事件,因为一般来说,每个线程都必须是可单独中断的。简言之,我的问题是“为什么一个线程终止会导致另一个线程挂起?”谢谢。不管您是在OnClose()中调用它还是在其他方法中调用它。通过在每个线程中使用一个关闭事件,您还可以单独结束每个线程。对不起,您是在谈论进程终止事件吗?请注意,我不关心进程终止。让我们把它当作一个程序来打断所有的线程。例如,我有“停止处理”菜单项,它不会关闭应用程序,但会中断所有线程,如上图所示。我不能无限期地等待事件,因为一般来说,每个线程都必须是可单独中断的。简言之,我的问题是“为什么一个线程终止会导致另一个线程挂起?”谢谢。不管您是在OnClose()中调用它还是在其他方法中调用它。通过对每个线程使用一个关闭事件,还可以单独结束每个线程。
procedure TLayerThread.Execute;
begin
FLayer.FIsActive := true;
...............
repeat
 //
 if Terminated or
   FLayer.FTerminating or
   (FLayer.FEvent = INVALID_HANDLE_VALUE) then
   begin
     break;
   end;
 //
 Fres := WaitForSingleObject(FLayer.FEvent, 100); <<<<<<<<<<<<<<<<<<<<<<<<
until Fres <> WAIT_TIMEOUT;
...........
FLayer.FIsActive := false;
end;
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
.................
        LeaveCriticalSection(ThreadLock);
        try
          WaitForSingleObject(SyncProc.Signal, INFINITE);<<<<<<<<<<<<<<<<<<<<<<
        finally
          EnterCriticalSection(ThreadLock);
        end;
..................