"Emergency" 全线程 IOmniParallelTask 终止
"Emergency" termination of omnithread IOmniParallelTask
背景
我有一个单元测试,我在其中检查我的处理程序代码在多线程压力下是否表现良好:
procedure TestAppProgress.TestLoopedAppProgressRelease_SubThread;
begin
var bt:=Parallel.ParallelTask.NumTasks(1).NoWait.Execute(
procedure
begin
SetWin32ThreadName('TestLoopedAppProgressRelease_SubThread');
RunLoopedAppProgressRelease;
end
);
lSuccess:=bt.WaitFor(cRunLoopTimerMilliSecs*2);
if not lSuccess then
bt.Terminate; // emergency termination, unit test failed <<< How do I do this?
Check(lSuccess,'Failed to finish within expected time');
end;
万一并行线程未能在预期时间内完成,则说明出了点问题,我的检查失败了。
不幸的是,如果并行任务挂起,它永远不会结束,并且我的单元测试会冻结,因为在等待永无止境的并行任务完成的例程结束时释放了 bt 接口。
所以我需要以 evil 方式关闭我的并行任务。
注意 1:这是一个单元测试,我不太关心线程清理:如果单元测试失败,无论如何都需要修复一些东西。我只是不希望我的整个单元测试套件 hang/freeze,而只是报告失败并继续我套件中的下一个测试。
注意 2:可以省略 Numthreads(1) 或任意数量的线程。
问题:如何强制终止IOmniParallel
任务?
好吧,我应该做更好的研究。这是单后台线程的解决方案,只需使用IOmniTaskControl
接口:
procedure TestAppProgress.TestLoopedAppProgressRelease_SubThread;
begin
var lTask:=CreateTask(
procedure (const aTask:IOmniTask)
begin
RunLoopedAppProgressRelease;
end,
'TestLoopedAppProgressRelease_SubThread'
);
lTask.Run;
var lSuccess:=lTask.WaitFor(cRunLoopTimerMilliSecs*2);
if not lSuccess then
lTask.Terminate; // emergency termination, unit test failed
Check(lSuccess,'Failed to finish within expected time');
end;
如果你想在多个子线程中 运行 它,你需要将它包装在 IOmniTaskGroup
:
procedure TestAppProgress.TestLoopedAppProgressRelease_MultiSubThread;
const cThreads=4;
begin
var lTaskGroup:=CreateTaskGroup;
for var i:=1 to cThreads do
begin
var lTask:=CreateTask(
procedure (const aTask:IOmniTask)
begin
RunLoopedAppProgressRelease;
end,
'TestLoopedAppProgressRelease_SubThread '+i.ToString
);
lTaskGroup.Add(lTask);
end;
lTaskGroup.RunAll;
var lSuccess:=lTaskGroup.WaitForAll(cRunLoopTimerMilliSecs*2);
if not lSuccess then
lTaskGroup.TerminateAll; // emergency termination, unit test failed
Check(lSuccess,'Failed to finish within expected time');
end;
在我的调试器中使用 delays/breakpoints 我验证了单元测试(错误)处理现在按预期工作。这包括由于终止线程导致的预期内存泄漏。
我仍然觉得 IOmniParallelTask
应该有一个 Terminate
类似于 IOmniTask
和 IOmniTaskGroup
中的方法
背景
我有一个单元测试,我在其中检查我的处理程序代码在多线程压力下是否表现良好:
procedure TestAppProgress.TestLoopedAppProgressRelease_SubThread;
begin
var bt:=Parallel.ParallelTask.NumTasks(1).NoWait.Execute(
procedure
begin
SetWin32ThreadName('TestLoopedAppProgressRelease_SubThread');
RunLoopedAppProgressRelease;
end
);
lSuccess:=bt.WaitFor(cRunLoopTimerMilliSecs*2);
if not lSuccess then
bt.Terminate; // emergency termination, unit test failed <<< How do I do this?
Check(lSuccess,'Failed to finish within expected time');
end;
万一并行线程未能在预期时间内完成,则说明出了点问题,我的检查失败了。 不幸的是,如果并行任务挂起,它永远不会结束,并且我的单元测试会冻结,因为在等待永无止境的并行任务完成的例程结束时释放了 bt 接口。
所以我需要以 evil 方式关闭我的并行任务。
注意 1:这是一个单元测试,我不太关心线程清理:如果单元测试失败,无论如何都需要修复一些东西。我只是不希望我的整个单元测试套件 hang/freeze,而只是报告失败并继续我套件中的下一个测试。
注意 2:可以省略 Numthreads(1) 或任意数量的线程。
问题:如何强制终止IOmniParallel
任务?
好吧,我应该做更好的研究。这是单后台线程的解决方案,只需使用IOmniTaskControl
接口:
procedure TestAppProgress.TestLoopedAppProgressRelease_SubThread;
begin
var lTask:=CreateTask(
procedure (const aTask:IOmniTask)
begin
RunLoopedAppProgressRelease;
end,
'TestLoopedAppProgressRelease_SubThread'
);
lTask.Run;
var lSuccess:=lTask.WaitFor(cRunLoopTimerMilliSecs*2);
if not lSuccess then
lTask.Terminate; // emergency termination, unit test failed
Check(lSuccess,'Failed to finish within expected time');
end;
如果你想在多个子线程中 运行 它,你需要将它包装在 IOmniTaskGroup
:
procedure TestAppProgress.TestLoopedAppProgressRelease_MultiSubThread;
const cThreads=4;
begin
var lTaskGroup:=CreateTaskGroup;
for var i:=1 to cThreads do
begin
var lTask:=CreateTask(
procedure (const aTask:IOmniTask)
begin
RunLoopedAppProgressRelease;
end,
'TestLoopedAppProgressRelease_SubThread '+i.ToString
);
lTaskGroup.Add(lTask);
end;
lTaskGroup.RunAll;
var lSuccess:=lTaskGroup.WaitForAll(cRunLoopTimerMilliSecs*2);
if not lSuccess then
lTaskGroup.TerminateAll; // emergency termination, unit test failed
Check(lSuccess,'Failed to finish within expected time');
end;
在我的调试器中使用 delays/breakpoints 我验证了单元测试(错误)处理现在按预期工作。这包括由于终止线程导致的预期内存泄漏。
我仍然觉得 IOmniParallelTask
应该有一个 Terminate
类似于 IOmniTask
和 IOmniTaskGroup