睡眠在线程中的替代方案
Alternative to sleep inside a thread
各种答案表明,睡在线程内是个坏主意,例如:避免睡眠。为什么?通常给出的一个原因是,如果线程正在休眠,则很难优雅地退出线程(通过发出终止信号)。
比方说,我想定期检查网络文件夹中的新文件,可能每10秒检查一次。这似乎非常适合优先级设置为低(或最低)的线程,因为我不希望潜在的耗时文件I/O影响我的主线程。
有哪些替代方案?代码在Delphi中给出,但同样适用于任何多线程应用程序:
procedure TNetFilesThrd.Execute();
begin
try
while (not Terminated) do
begin
// Check for new files
// ...
// Rest a little before spinning around again
if (not Terminated) then
Sleep(TenSeconds);
end;
finally
// Terminated (or exception) so free all resources...
end;
end;
一个小的修改可能是:
// Rest a little before spinning around again
nSleepCounter := 0;
while (not Terminated) and (nSleepCounter < 500) do
begin
Sleep(TwentyMilliseconds);
Inc(nSleepCounter);
end;
但这仍然涉及睡眠。。。
while not Terminated do
begin
// Check for new files
// ...
// Rest a little before spinning around again
FTerminationEvent.WaitFor(TenSeconds);
end;
为了终止,您需要覆盖TerminatedSet
:
procedure TMyThread.TerminatedSet;
begin
inherited;
FTerminationEvent.SetEvent; // abandon the wait in the thread method
end;
对该事件的等待要么超时,要么由于该事件已发出信号而终止。这允许您的线程暂停一段时间,而不会给CPU带来负担,而且还可以对终止请求保持响应。
如果这是我的工作,我想我会用一个包含TTimer的包装类来解决它,每10秒生成一个新线程。
生成一个新线程的成本有些高,但如果是每10秒才执行一次的操作,我认为对主线程的性能影响可以忽略不计。
步骤:
- 创建一个包装类TMyFileSearcher
- 让它包含一个TTimer
- 每次定时器命中时,生成一个新线程并搜索文件
- 向TMyFileSearcher添加一个OnTerminate处理程序,以处理返回的文件
还有一些其他的考虑因素,比如跟踪线程是否已经派生,这样就不会在旧线程运行时创建新线程。
但是,除此之外,我认为它应该非常直接地实施。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 对于 ~95% 写入/5% 读取线程安全的无序列图,有没有一个简单的解决方案?
- vtkUnstructuredGrid->GetPoint() 的线程安全只读替代方案
- parallel_for中互斥锁的多线程替代方案
- 从QTcpSocket上的数据流中连续运行复杂算法的最佳Qt线程解决方案是什么
- 暂停和恢复线程的最佳解决方案是什么?
- std::map的线程安全替代方案
- 重构多线程方案的单线程 GUI 代码
- 多线程 – 已知的相似性解决方案
- 英特尔线程构建模块替代方案和许可
- 非阻塞定时器和服务器的解决方案是提升线程
- 多线程搜索的解决方案空间很大
- 黑客攻击线程安全是"最佳"行动方案吗?
- IncrediBuild在一个线程中编译Visual Studio 2010/2012解决方案的一些项目
- 等待条件的非线程替代方案.(编辑:Proactor模式与boost.asio?)