如何知道线程池中的线程挂起/冻结
我有线程池的任务队列,每个任务都有冻结锁定其正在使用的所有资源的倾向。并且除非重新启动服务,否则这些无法释放。
ThreadPool 中有没有办法知道它的线程已经被冻结?我有一个使用超时的想法(虽然我仍然不知道如何写),但我认为它不安全,因为处理的时间长度不统一。
I have queue of tasks for the ThreadPool, and each task has a tendency to froze locking up all the resources it is using. And these cant be released unless the service is restarted.
Is there a way in the ThreadPool to know that its thread is already frozen? I have an idea of using a time out, (though i still dont know how to write it), but i think its not safe because the length of time for processing is not uniform.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不想在这里太自以为是,但真正找出问题所在并解决它是解决僵局的最佳方法。
除非你有一个合理的架构\设计\理由来首先选择受害者,否则不要这样做 - 期间。当线程正在做某件事时,随意地敲打它们的头,这几乎会导致灾难。
I don't want to be too presumptuous here, but a good dose of actually finding out what the problem is and fixing it is the best course with deadlocks.
Unless you have a sound architecture\design\reason to choose victims in the first place, don't do it - period. It's pretty much a recipe for disaster to arbitrarily bash threads over the head when they're in the middle of something.
(这可能有点低级,但至少它是一个简单的解决方案。由于我不了解 C# 的 API,这是任何使用线程池的语言的通用解决方案。)
插入看门狗每个实际任务之后的任务,用当前时间更新时间值。如果该值大于最大任务运行时间(例如 10 秒),您就知道有什么东西被卡住了。
您可以在未来 10 秒内连续设置和重置一些计时器,而不是设置时间并轮询它。当它触发时,任务已挂起。
最好的方法可能是将每个任务包装在一个“Watchdog”任务类中,该类会自动执行此操作。这样,完成后,您可以清除计时器,并且还可以设置每个任务的超时,这可能很有用。
显然,线程池中的每个线程都需要一个时间/计时器对象,但这可以通过线程局部变量来解决。
请注意,此解决方案不需要您修改任务的代码。它仅修改将任务放入池中的代码。
(This is perhaps a bit lowlevel, but at least it is a simple solution. As I don't know C#'s API, this is a general solution for any language using thread-pools.)
Insert a watchdog task after each real task that updates a time value with the current time. If this value is larger than you max task run time (say 10 seconds), you know that something is stuck.
Instead of setting a time and polling it, you could continuously set and reset some timers 10 secs into the future. When it triggers, a task has hung.
The best way is probably to wrap each task in a "Watchdog" Task class that does this automatically. That way, upon completion, you'd clear the timer, and you could also set a per-task timeout, which might be useful.
You obviously need one time/timer object for each thread in the threadpool, but that's solvable via thread-local variables.
Note that this solution does not require you to modify your tasks' code. It only modifies the code putting tasks into the pool.
一种方法是使用看门狗定时器(这种解决方案通常在硬件中完成,但也适用于软件)。
让每个线程至少每五秒一次将线程特定值设置为 1(例如)。
然后你的看门狗定时器每十秒唤醒一次(同样,这只是一个示例图)并检查以确保所有值都为 1。如果它们不是 1,则线程已锁定。
然后看门狗定时器将它们全部设置为 0,并在下一个周期返回休眠状态。
如果你的工作线程以这样的方式编写,以便它们能够在非冻结条件下及时设置值,那么这个方案就可以正常工作。
第一个锁定的线程不会将其值设置为 1,这将在下一个周期被看门狗定时器检测到。
然而,更好的解决方案是首先找出线程冻结的原因并修复它。
One way is to use a watchdog timer (a solution usually done in hardware but applicable to software as well).
Have each thread set a thread-specific value to 1 at least once every five seconds (for example).
Then your watchdog timer wakes every ten seconds (again, this is an example figure only) and checks to ensure that all the values are 1. If they're not 1, then a thread has locked up.
The watchdog timer then sets them all to 0 and goes back to sleep for the next cycle.
Providing your worker threads are written in such a way so that they will be able to set the values in a timely manner under non-frozen conditions, this scheme will work okay.
The first thread that locks up will not set its value to 1, and this will be detected by the watchdog timer on the next cycle.
However, a better solution is to find out why the threads are freezing in the first place and fix that.