如何在线程中每秒执行一个动作?
问题描述:
我知道定时器是由执行的周期性动作,但我不知道,如果计时器是在一个线程来执行定期操作的最佳方式,我想要做的是正从工作线程的一些信息,要更清楚:有一个主线程需要获得另一个线程(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
withing这个循环,那么假设我有许多工人:,它宁愿:
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;
所以,我想实现的是:主线程必须退出循环只有当:
- 所有工作线程终止(后立即终止),而主线程正在等待获得属性值,如果线程终止,主线程退出循环,如果没有,就继续等待,直到经过时间= 1秒,并获得新的价值。
- 条件为假。 我将条件设置为false没有问题,因为我必须计算每次迭代的结果并确定其新值。
我希望我在我解释清楚。
感谢您的回复。
答
WaitForMultipleObjects
的确,你应该调用的函数。你的问题虽然是你没有检查返回值。无论何时调用Windows API函数,都有一条经验法则:
总是检查函数返回的值。
你会避免很多问题,如果你遵循的规则。
在这种情况下documentation说,传递True
为bWaitAll
时:
- 的WAIT_OBJECT_0甲返回值(WAIT_OBJECT_0 + nCount- 1)意味着该函数返回,因为所有指定的对象被发信号。
- WAIT_TIMEOUT的返回值表示函数返回,因为指定的超时时间过去。
- 返回值WAIT_FAILED表示由于某种原因调用失败,并且您应该致电
GetLastError
以查明原因是什么。
请注意,您不必担心WAIT_ABANDONED_0到(WAIT_ABANDONED_0 + nCount- 1)的情况下,因为你没有传递任何互斥对象。
最简单的方法是在循环中调用“Sleep(1000)”,在每次循环迭代中执行您的操作。或者,使用'CreateWaitableTimer()'和'WaitForSingleObject()'而不是'Sleep()'。 –
你为什么认为计时器不是最好的方法? –
抱歉不清楚,请参阅我的编辑。 – Safa