如何在线程中每秒执行一个动作?
How to execute an action every second in a thread?
我知道定时器是用来执行周期性动作的,但我不确定定时器是否是在线程中执行周期性动作的最佳方式,我想做的是从工作线程获取一些信息,更清楚一点:有一个主线程需要获取另一个线程(woker)的属性,这个是变体,这就是为什么我需要在每个时间间隔获取它的值。
有点像:
procedure mainThread.execute;
begin
// every second :
val := workerThread.property;
end;
正常情况下,主线程需要等待一秒钟,然后获取值,例如:
procedure mainThread.execute;
begin
while (condition) do
begin
sleep(1000);
val := workerThread.property;
end;
但是,如果工作线程终止了,而主线程还在等待获取值 sleep(1000)
,这会导致时间丢失,因为主线程应该在工作线程结束时立即退出循环终止。如果工作线程已经终止其工作,我不希望主线程等待(如果工作线程花费的时间少于 1 秒,则无需获取 属性 值),这就是我不应该这样做的原因就这样
我还考虑过在该循环中使用 waitformultipleobjects
,所以假设我有很多工人:,它宁愿是:
procedure mainThread.execute;
begin
while (condition) do
begin
waitForMultipleObjects(Threads, @Array, True, 1000);
//If elapsed Time < 1000 , this means that all threads terminated, then main thread must quit this loop
//If elapsed Time = 1000 :
val := workerThread.property;
// Calculate the new value of condition
end;
所以,我想要实现的是:主线程只有在以下情况下才必须退出循环:
- 所有工作线程终止(终止后立即终止):当主线程正在等待获取 属性 值时,如果线程终止,则主线程退出循环,否则,它将继续等待直到经过time = 1 s 并获取新值。
- 条件不成立。
我可以将条件设置为 false,因为每次迭代我都必须计算一些东西并确定它的新值。
我希望我的解释很清楚。
感谢您的回复。
WaitForMultipleObjects
确实是您应该调用的函数。你的问题是你没有检查 return 值。每当您调用 Windows API 函数时,这里有一条经验法则:
Always check the value returned by the function.
如果你遵循这条规则,你会避免很多问题。
在这种情况下,documentation 表示,当为 bWaitAll
传递 True
时:
- WAIT_OBJECT_0的return值到(WAIT_OBJECT_0 + nCount– 1)意味着函数 returned 因为所有指定的对象都已发出信号。
- WAIT_TIMEOUT 的 return 值表示函数 return 已运行,因为指定的超时已过。
- WAIT_FAILED的return值表示由于某种原因调用失败,您应该调用
GetLastError
找出原因那是什么原因。
请注意,您无需担心 WAIT_ABANDONED_0 到 (WAIT_ABANDONED_0 + nCount– 1) 大小写,因为您没有传递任何互斥对象。
我知道定时器是用来执行周期性动作的,但我不确定定时器是否是在线程中执行周期性动作的最佳方式,我想做的是从工作线程获取一些信息,更清楚一点:有一个主线程需要获取另一个线程(woker)的属性,这个是变体,这就是为什么我需要在每个时间间隔获取它的值。 有点像:
procedure mainThread.execute;
begin
// every second :
val := workerThread.property;
end;
正常情况下,主线程需要等待一秒钟,然后获取值,例如:
procedure mainThread.execute;
begin
while (condition) do
begin
sleep(1000);
val := workerThread.property;
end;
但是,如果工作线程终止了,而主线程还在等待获取值 sleep(1000)
,这会导致时间丢失,因为主线程应该在工作线程结束时立即退出循环终止。如果工作线程已经终止其工作,我不希望主线程等待(如果工作线程花费的时间少于 1 秒,则无需获取 属性 值),这就是我不应该这样做的原因就这样
我还考虑过在该循环中使用 waitformultipleobjects
,所以假设我有很多工人:,它宁愿是:
procedure mainThread.execute;
begin
while (condition) do
begin
waitForMultipleObjects(Threads, @Array, True, 1000);
//If elapsed Time < 1000 , this means that all threads terminated, then main thread must quit this loop
//If elapsed Time = 1000 :
val := workerThread.property;
// Calculate the new value of condition
end;
所以,我想要实现的是:主线程只有在以下情况下才必须退出循环:
- 所有工作线程终止(终止后立即终止):当主线程正在等待获取 属性 值时,如果线程终止,则主线程退出循环,否则,它将继续等待直到经过time = 1 s 并获取新值。
- 条件不成立。 我可以将条件设置为 false,因为每次迭代我都必须计算一些东西并确定它的新值。
我希望我的解释很清楚。
感谢您的回复。
WaitForMultipleObjects
确实是您应该调用的函数。你的问题是你没有检查 return 值。每当您调用 Windows API 函数时,这里有一条经验法则:
Always check the value returned by the function.
如果你遵循这条规则,你会避免很多问题。
在这种情况下,documentation 表示,当为 bWaitAll
传递 True
时:
- WAIT_OBJECT_0的return值到(WAIT_OBJECT_0 + nCount– 1)意味着函数 returned 因为所有指定的对象都已发出信号。
- WAIT_TIMEOUT 的 return 值表示函数 return 已运行,因为指定的超时已过。
- WAIT_FAILED的return值表示由于某种原因调用失败,您应该调用
GetLastError
找出原因那是什么原因。
请注意,您无需担心 WAIT_ABANDONED_0 到 (WAIT_ABANDONED_0 + nCount– 1) 大小写,因为您没有传递任何互斥对象。