- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
创建一个线程(TThreadStarter),然后它将创建许多工作线程,并且必须等待它们完成才能继续。它必须在 Linux 和 Windows 下都能工作。
下面的方法似乎是一个解决方案。但这是一件好事吗?你会采取不同的做法吗?
1) 创建所有线程并将其放入一个数组中,然后运行该数组并调用 Start。
2) 然后只需再次运行数组并调用 WaitFor 即可停止执行对于调用线程,直到所有线程都完成。
procedure TThreadStarter.Execute;
var i1:integer;
begin
for i1:=1 to WORK_THREAD_COUNT do ThreadArray[i1].Start;
for i1:=1 to WORK_THREAD_COUNT do ThreadArray[i1].WaitFor;
..Do some work
end;
我使用 Lazarus 和 FreePascal。
最佳答案
等待(几乎)任意数量的工作线程的解决方案(仅限 Windows)。
从您的 MainWorkerThread
(不是普通的主线程)调用 WaitForThreads
函数,并传入您想要等待的所有线程句柄的数组。
interface
uses
Windows, SysUtils, Classes;
type
THandleDynArray = array of THandle;
TMaximum_Wait_Objects_Handles = array[0..MAXIMUM_WAIT_OBJECTS - 1] of THandle;
EMaximum_Handles_Exceeded = class(Exception);
TThreadWaitForThreads = class(TThread)
strict private
FarrHandle: TMaximum_Wait_Objects_Handles;
FThreadWaitCount: 0..MAXIMUM_WAIT_OBJECTS;
protected
procedure Execute; override;
public
procedure AddHandle(Handle: THandle); overload;
procedure AddHandle(HandleArray: THandleDynArray); overload;
procedure ClearHandles;
end;
procedure WaitForThreads(const Handles: THandleDynArray);
implementation
procedure WaitForThreads(const Handles: THandleDynArray);
var
Wait_Result: cardinal;
arrHandle: TMaximum_Wait_Objects_Handles;
arrWaitThreads: array[0..MAXIMUM_WAIT_OBJECTS - 1] of TThreadWaitForThreads;
WaitThreadsCount, i: integer;
begin
if Length(Handles) <= 0 then
exit;
if Length(Handles) > MAXIMUM_WAIT_OBJECTS then
begin
WaitThreadsCount := Length(Handles) div MAXIMUM_WAIT_OBJECTS;
for i := 0 to WaitThreadsCount - 1 do
begin
arrWaitThreads[i] := TThreadWaitForThreads.Create(true);
arrHandle[i] := arrWaitThreads[i].Handle;
arrWaitThreads[i].AddHandle(Copy(Handles, MAXIMUM_WAIT_OBJECTS * i, MAXIMUM_WAIT_OBJECTS));
end;
try
if Length(Handles) mod MAXIMUM_WAIT_OBJECTS > 0 then
Move(Handles[MAXIMUM_WAIT_OBJECTS * WaitThreadsCount], arrHandle[WaitThreadsCount], (Length(Handles) - WaitThreadsCount * MAXIMUM_WAIT_OBJECTS) * SizeOf(THandle));
for i := 0 to WaitThreadsCount - 1 do
arrWaitThreads[i].Resume;
repeat
Wait_Result := WaitForMultipleObjectsEx(WaitThreadsCount + Length(Handles) - WaitThreadsCount * MAXIMUM_WAIT_OBJECTS, @arrHandle, true, 10, true);
Application.ProcessMessages;
until ((Wait_Result <> WAIT_TIMEOUT)
and (Wait_Result <> WAIT_IO_COMPLETION));
finally
for i := 0 to WaitThreadsCount - 1 do
begin
arrWaitThreads[i].Terminate; // terminating all WaitThreads to be on the safe side
arrWaitThreads[i].Free;
end;
end;
end
else
begin
repeat
Wait_Result := WaitForMultipleObjectsEx(Length(Handles), @Handles[0], true, 10, true);
Application.ProcessMessages;
until ((Wait_Result <> WAIT_TIMEOUT)
and (Wait_Result <> WAIT_IO_COMPLETION));
end;
end;
{ TThreadWaitForThreads }
procedure TThreadWaitForThreads.AddHandle(Handle: THandle);
begin
if FThreadWaitCount < MAXIMUM_WAIT_OBJECTS then
begin
FarrHandle[FThreadWaitCount] := Handle;
Inc(FThreadWaitCount);
end
else
raise EMaximum_Handles_Exceeded.Create('You can only wait for ' + IntToStr(MAXIMUM_WAIT_OBJECTS) + ' Threads!');
end;
procedure TThreadWaitForThreads.AddHandle(HandleArray: THandleDynArray);
begin
if FThreadWaitCount + Length(HandleArray) <= MAXIMUM_WAIT_OBJECTS then
begin
Move(HandleArray[0], FarrHandle[FThreadWaitCount], SizeOf(THandle) * Length(HandleArray));
Inc(FThreadWaitCount, Length(HandleArray));
end
else
raise EMaximum_Handles_Exceeded.Create('You want to wait for ' + IntToStr(FThreadWaitCount + Length(HandleArray)) + ' threads, but you can only wait for ' + IntToStr(MAXIMUM_WAIT_OBJECTS) + '!');
end;
procedure TThreadWaitForThreads.ClearHandles;
begin
FThreadWaitCount := 0;
ZeroMemory(@FarrHandle, SizeOf(FarrHandle));
end;
procedure TThreadWaitForThreads.Execute;
var
Wait_Result: cardinal;
begin
if FThreadWaitCount = 0 then
exit;
repeat
Wait_Result := WaitForMultipleObjectsEx(FThreadWaitCount, @FarrHandle, true, 10, true);
until ((Wait_Result <> WAIT_TIMEOUT)
and (Wait_Result <> WAIT_IO_COMPLETION))
or Terminated;
ClearHandles;
end;
end.
关于multithreading - 多个连续线程上的 TThread.WaitFor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27865019/
我在进程上使用 waitFor 命令时遇到问题。我的代码是这样的 //preconditions try{ // lock the work station Process p= Runtim
我正在尝试在 puppeteer 上运行我的第一个代码。 puppeteer v1.20.0 Node v8.11.3 Npm v5.6.0 这是一个基本示例,但它不起作用: const puppet
我有一个在 .jar 中编译的 Java 程序,因此最终用户实际上无法在控制台中直接按 ctrl+c。 他们必须在任务管理器中结束java进程。 但是,还有一种更简单的方法,不是吗? public c
我关注 a tutorial关于 react 测试。本教程有一个像这样的简单组件,用于展示如何测试异步操作: import React from 'react' const TestAsync = (
创建一个线程(TThreadStarter),然后它将创建许多工作线程,并且必须等待它们完成才能继续。它必须在 Linux 和 Windows 下都能工作。 下面的方法似乎是一个解决方案。但这是一件好
我试图找出T-SQL中WAITFOR的性能或内部实现,已经经历了MSDN Stackoverflow 和其他网站没有运气,这是我的问题 对于下面的代码,我想从表 DUMMY 中删除前 10,000 行
在 Windows 7 64 位上,运行 64 位 Java 1.7.0_17 ,下面显示的 p.waitFor() 永远不会返回。 String move_command="cmd.exe /c x
我正在尝试从命令行运行 Matlab 脚本,而我又从 Java 调用该脚本。我使用循环多次调用该脚本,并且在每次迭代中我希望我的 Java 程序暂停,直到 Matlab 脚本结束并退出 Matlab。
我正在尝试从 Java 运行命令行命令,快速的健全性检查让我意识到我遇到问题的原因是我无法获得下面的 pr.waitFor() 调用上类。该程序在不到 30 秒内结束,并且在“foo:”之后不打印任何
我正在构建一个应用程序,该应用程序应该在我的 Windows PC 上启动其他应用程序。当应用程序启动时,我的代码应该等到我关闭该程序才能继续执行。 System.out.println("Start
String command = "javac -cp .:../sqljdbc.jar SetHash.java"; Process child = Runtime.getRuntime().
我收到 16 位 MS-DOS 子系统错误,提示“为应用程序设置环境时出错。选择‘关闭’终止应用程序。”当我尝试运行一个应该下载程序的java小程序时。 这是源代码: if(getConfig(mai
我有一个 JAVA 代码,正在其中执行 perl 脚本。有些脚本不返回响应代码,但需要密码才能执行。在这些情况下,我的代码不会返回,并且 process.waitFor() 会无休止地等待。 有什么办
在运行外部脚本时,我想同时或分别读取该脚本的 ErrorStream 和 OutputStream,然后进一步处理它们。因此,我为其中一个流启动了一个 Thread。不幸的是,Process 似乎并没
我正在尝试使用 ProcessBuilder 来执行像“ls”命令这样简单的操作。我已经阅读了有关 waitFor() 调用返回之前需要消耗的进程流的问题,但即使错误重定向到输出并消耗流,进程也永远不
我在我的应用程序中使用以下代码... Process process = Runtime.getRuntime().exec( "perl " + perlScript + " " + pro
我正在尝试从 java 的 root android 设备中的/data/data 文件夹中获取所有文件和文件夹。我有在 Windows cmd 中正常工作的命令: adb -s shell su
以下代码总是返回 1。我不明白为什么。 String executeCmd[] = {"mysql"," -u" + dbUser," -p" + dbPass," -A"," -D"+dbName
我正在尝试运行 mysql 来执行来自 java 的一些文件。输入是从文件中读取的,应该通过管道传输到 mysql 进程中,一切似乎都正常,但是行 int exitCode = proc.waitFo
我对casperJS比较陌生。我有一个脚本,我想在页面B中执行操作(即验证用户的确认邮件),然后在页面A中继续执行。代码片段如下 casper.waitFor(function(){ retur
我是一名优秀的程序员,十分优秀!