Linux 对于 pthread,如何从主线程杀死子线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3822674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 23:39:47  来源:igfitidea点击:

For pthread, How to kill child thread from the main thread

clinuxmultithreadingpthreads

提问by terry

I use pthread_create to create several child threads. At a time, the main thread wants to kill all child threads or there will be segment falut. Which function should I use to finish that? I searched the answer from google and got function like pthread_kill. But I did not know which signal should I send to the child thread to kill them. My running environment is RHEL 5.4 and programming language is C.

我使用 pthread_create 创建多个子线程。一次,主线程想要杀死所有子线程,否则会出现段错误。我应该使用哪个函数来完成它?我从谷歌搜索了答案,得到了 pthread_kill 之类的功能。但是我不知道应该向子线程发送哪个信号来杀死它们。我的运行环境是RHEL 5.4,编程语言是C。

采纳答案by torak

It is possible to "cancel" a thread using pthread_cancel. However, this isn't typically best practice though under extreme circumstances like a SEGFAULT it may be conisdered a reasonable approach.

可以使用“取消”线程pthread_cancel。然而,这通常不是最佳实践,尽管在像 SEGFAULT 这样的极端情况下,它可能被认为是一种合理的方法。

回答by e2-e4

You should send SIG_TERM to each of your threads, using

您应该将 SIG_TERM 发送到您的每个线程,使用

  int pthread_kill(pthread_t thread, int sig);

A quick way to get rid of all threads (besides the main) is to fork() and keep going with the child.
Not hyper clean...

摆脱所有线程(除了主线程)的一种快速方法是 fork() 并继续使用子线程。
不是超级干净...

  if (fork()) exit(0); // deals also with -1...

回答by Bill Gribble

In general, you don't really want to violently kill a child thread, but instead you want to ask it to terminate. That way you can be sure that the child is quitting at a safe spot and all its resources are cleaned up.

通常,您并不真的想暴力杀死子线程,而是想要求它终止。这样你就可以确保孩子在一个安全的地方戒烟,并且它的所有资源都被清理干净。

I generally do this with a small piece of shared state between parent and child to allow the parent to communicate a "quit request" to each child. This can just be a boolean value for each child, protected by a mutex. The child checks this value periodically (every loop iteration, or whatever convenient checkpoints you have in your child thread). Upon seeing "quit_request" being true, the child thread cleans up and calls pthread_exit.

我通常在父母和孩子之间使用一小部分共享状态来执行此操作,以允许父母向每个孩子传达“退出请求”。这可以只是每个孩子的布尔值,受互斥锁保护。子线程会定期检查此值(每次循环迭代,或您子线程中的任何方便的检查点)。看到“quit_request”为真后,子线程会清理并调用pthread_exit.

On the parent side, the "kill_child" routine looks something like this:

在父端,“kill_child”例程如下所示:

acquire shared mutex
set quit_request to true 
pthread_join the child 

The pthread_join may take some time, depending on how frequently the child checks its quit request. Make sure your design can handle whatever the delay may be.

pthread_join 可能需要一些时间,具体取决于子进程检查退出请求的频率。确保您的设计可以处理任何延迟。

回答by johnnycrash

You can use a global variable for the entire program.

您可以对整个程序使用全局变量。

int _fCloseThreads;

int _fCloseThreads;

Set it to 1 when you want the threads to quit execution. Have the threads check that variable in their "loop" and nicely quit when it is set to 1. No need to protect it with a mutex.

当您希望线程退出执行时,将其设置为 1。让线程在它们的“循环”中检查该变量,并在它设置为 1 时很好地退出。无需使用互斥锁保护它。

You need to wait for the threads to quit. You can use join. Another way is to increment a counter when a thread enters its thread proc and then decriment the counter when it exits. The counter would need to be a global of sorts. Use gcc atomic ops on the counter. The main thread, after setting fCloseThreads, can wait on the counter to go to zero by looping, sleeping, and checking the count.

您需要等待线程退出。您可以使用连接。另一种方法是在线程进入其线程过程时递增计数器,然后在退出时递减计数器。计数器需要是某种全局变量。在计数器上使用 gcc atomic ops。主线程在设置 fCloseThreads 后,可以通过循环、休眠和检查计数等方式等待计数器归零。

Finally, you might checkout pthread_cleanup_push and pop. They are a model for allowing a thread to cancel anywhere in its code (uses a longjump) and then call a final cleanup function before exiting threadproc. You basicly put cleanup_push at the top of your threadproc and cleanup_pop at the bottom, create an unwind function, and then at certain cancelation points a thread canceled by a call to pthread_cancel() will longjump back to threadproc and call the unwind function.

最后,您可以检查 pthread_cleanup_push 和 pop。它们是一种模型,允许线程在其代码中的任何位置取消(使用 longjump),然后在退出 threadproc 之前调用最终清理函数。您基本上将 cleanup_push 放在 threadproc 的顶部,将 cleanup_pop 放在底部,创建一个 unwind 函数,然后在某些取消点,通过调用 pthread_cancel() 取消的线程将 longjump 回到 threadproc 并调用 unwind 函数。