可能的重复:
如何优雅地停止长时间执行的线程?
你好。
我有一个需要执行操作的后台线程,它一直工作正常,除了一种情况:资源损坏时。发生这种情况时,线程会在 Execute 方法中的 Load(对该资源)调用中被阻止。
当发生这种情况时,线程将不会响应 Terminate 方法(来自主线程的调用)并被阻止。
所以,我的问题是:如何正确终止被阻止的线程(从主线程)。不,我无法修改加载资源的类,或者之前也不知道资源是否已损坏。
Possible Duplicate:
How to stop long executing threads gracefully?
Hello.
I have a background thread which needs to perform an operation, it works fine all of the time except in one case : when the resource is corrupted. When that happens the thread gets Blocked in the Load (to that resource) calls in the Execute method.
When that happens the thread Won't respond to the Terminate method ( call from main thread ) and gets blocked.
So, my question is : How to properly terminate the blocked thread ( from the main thread ). And no I cannot modify the class which loads the resource, or neither know from before if the resource is corrupted or not.
发布评论
评论(1)
查找
TerminateThread()
WinAPI 函数。一些有用的解释可以在此处找到或查看MSDN 文档。
当然,终止后您必须查看线程中分配的任何资源是否未释放并适当地释放它。
更新
是的,使用
TerminateThread
是不好的做法(如注释中所述)。我很同意这个意见。但是“永远不要使用它,即使你真的需要使用它”从我的角度来看,建议太强烈并且非常理论化。现实世界充满了设计缺陷和有缺陷的第三方库。所提供的信息不足以就这种具体情况做出正确的决定。例如,这可能是临时解决方法,没有其他选择,等等。
因此,从理论上来看,正确的答案是:“如果无法控制如何“冻结”处理的后台线程中的步骤,则无法正确终止进程。”
从实际的角度来看,正确的答案是:“如果您无法控制如何“冻结”已处理的后台线程中的步骤,则无法正确终止进程。但是如果您意识到不能,但仍然需要这样的功能 - 使用 TerminateThread() API 调用”
关于 TerminateThread 与 TerminateProcess:
- 创建/终止进程比创建/终止线程需要更多资源
- 创建/终止过程更复杂=>更多错误地方
- TerminateProcess 不会立即终止并等待 I/O 操作完成 (MSDN) =>不适用于远程共享文件夹在读取时不可用的情况以及其他类似的 I/O 情况。
- 创建和终止进程比创建线程需要更多的用户权限,比较MSDN 此处和此处
关于资源释放:
终止线程时,线程堆栈自动释放(如 MSDN 中所述)。资源主要是主线程分配用于与后台线程通信的资源。例如内存结构、互斥体等。
Look for
TerminateThread()
WinAPI function.Some useful explanation can be found here or look at MSDN documentation.
Of course, after terminating you must look if any resources allocated in thread not freed and free it appropriately.
Update
Yes, using
TerminateThread
is bad practice (as specified in comments). I'm agree with this opinion. But "never use it, even if you really need to use it" recomendation it too strong from my point of view and very theoretic. Real world full of design flaws and buggy 3rd-party libraries.Information, given in question not enough for making right decision about this concrete situation. E.g. it may be temporary workaround with no alternatives, etc.
Therefore, from theoretic point of view right answer is : "There are no way to terminate process properly if you can't control how to "freezing" step in background thread processed."
From practical point of view right answer is: "There are no way to terminate process properly if you can't control how to "freezing" step in background thread processed. But if you realize that you can't, but still needs such functionality - use TerminateThread() API call"
About TerminateThread vs. TerminateProcess:
- Creating/terminating process requires more resources than creating/terminating thread
- Creating/terminating process more complicated => more place for bugs
- TerminateProcess don't terminates immediately and waits for I/O operations to complete (MSDN) => not a choice for scenario where remote shared folder becomes unavailable while reading and other similar I/O scenarios.
- Creating and terminating process requires more user privileges than creating thread, compare MSDN here and here
About resource freeing:
Thread stack freed automatically when terminating thread (as mentonied in MSDN). Resources is primarily resources, allocated by main thread for communication with background thread. E.g. memory structures, mutexes, etc.