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