如果分离一个正在执行永久循环的线程会发生什么?

huangapple go评论58阅读模式
英文:

What happens if you detach a thread that's executing a permanent loop?

问题

这相当于内存泄漏吗?用指针和动态分配的内存来类比,如果我丢失了一个指向我已分配内存的资源的指针,我就无法再删除或释放那块内存了。同样,如果我有一个正在运行无限循环的工作线程,并且将其分离,那是否算是泄漏呢?如果线程已被分离,就没有办法停止它的执行了吗?

英文:

Is this the equivalent of a leak? To use pointers and dynamically allocated memory as an analogy, if I lose a pointer to a resource that I've allocated memory for I can't delete or free that memory anymore. Likewise if I have a worker thread that's running an infinite loop and I detach the thread then is that a leak? There's no way to stop the thread executing if it's been detached?

答案1

得分: 1

以下是翻译好的部分:

如果线程决定自行退出,它将清理自己的内部数据结构,以防止内存泄漏(至少不是来自线程类本身的内存泄漏;通过join(),分离线程对象告诉它不要期望父线程通过join()来进行清理,所以正在退出的线程将执行清理)。如果线程继续运行,那么它分配的任何资源都将保持分配,尽管从技术上讲这不是内存泄漏,因为线程本身的代码(假定)仍然可以释放这些资源,如果需要的话。

仍然有一种方法可以停止线程的执行;你只需礼貌地请求它退出。如何请求取决于你,你可以通过将std::atomic<bool> pleaseQuit;变量设置为true来实现,然后依赖线程定期检查变量的值并在变量为true时退出,或者通过在管道或套接字上向线程发送一个字节,或通过其他方式。当然,这需要线程内部运行的代码的合作;没有一种好的/安全的方式可以单方面终止不合作的线程。

一旦你请求线程停止运行,通常希望阻塞,直到确保线程已停止,例如,这样你可以安全地释放线程在仍然存在时可能尝试访问的数据结构。为此,你需要使用join()线程,这意味着不应该使用detach(),因为分离的线程无法被连接。分离的线程只在你不关心清理的情况下有用(例如,因为你不希望线程停止运行)。

英文:

What happens is the thread keeps running, potentially forever. If the thread decides on its own to exit, it will clean up its own internal data structures so there won't be any memory leak (at least, not from the thread-class itself; detaching the thread object tells it not to expect any parent thread to do cleanup via join(), so the exiting thread will do that cleanup itself). If it keeps running, then whatever resources it has allocated will remain allocated, although technically it's not a memory leak because code in the thread itself still (presumably) has the ability to free those resources, if it wanted to.

There is still a way to stop the thread from executing; you simply have to ask it nicely to exit. How you ask it is up to you -- you could do it by setting a std::atomic&lt;bool&gt; pleaseQuit; variable to true, and relying on the thread to periodically check the variable's value and exit if it's true, or by sending a byte to the thread on a pipe or a socket, or by some other means. This does require the co-operation of the code running inside the thread, of course; there's no good/safe way to unilaterally kill an uncooperative thread.

Once you've asked the thread to stop running, you usually want to then block until you know that it the thread is guaranteed dead, e.g. so that you can safely deallocate data structures that the thread might try to access while it still exists. To do that, you'll need to join() the thread, which means you shouldn't detach() it since detached threads can't be joined. Detached threads are only useful in situations where you don't care about cleaning up (e.g. because you're not expecting the thread to ever stop running anyway)

huangapple
  • 本文由 发表于 2023年2月10日 11:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406710.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定