Ctrl + C:它会随着主进程一起杀死线程吗?
在运行线程程序并使用 Ctrl + C 反复终止主程序时,我在第二次运行时看到程序出现意外结果。但是,如果我让程序运行并自动退出,就没有问题。
所以,我的疑问是,Ctrl + C 是否也会随主进程一起杀死线程?
提前致谢。
While running a thread program and repeatedly killing the main program using Ctrl + C
, i see unexpected results in the program in second run. However, if i let the program run and voluntarily exit, there are no issues.
So, my doubt is, does Ctrl + C
, kill threads also along with the main process?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在多线程编程中,信号被传递到单个线程(通常在没有阻止该特定信号的线程中不可预测地选择)。然而,这并不意味着默认操作是终止进程的信号只会终止一个线程。事实上,没有办法在不杀死整个进程的情况下杀死单个线程。
只要您将
SIGINT
保留为终止进程的默认操作,只要至少有一个线程未阻止SIGINT
,它就会这样做。哪个线程解除阻塞并不重要,只要至少有一个线程解除阻塞即可,因此在应用程序背后创建线程的库代码应始终在调用pthread_create
之前阻塞所有信号,并在调用中恢复信号掩码之后的线程。In multithreaded programming, signals are delivered to a single thread (usually chosen unpredictably among the threads that don't have that particular signal blocked). However, this does not mean that a signal whose default action is to kill the process only terminates one thread. In fact, there is no way to kill a single thread without killing the whole process.
As long as you leave
SIGINT
with its default action of terminating the process, it will do so as long as at least one thread leavesSIGINT
unblocked. It doesn't matter which thread has it unblocked as long as at least one does, so library code creating threads behind the application's back should always block all signals before callingpthread_create
and restore the signal mask in the calling thread afterwards.好吧,
Ctrl + C
所做的唯一一件事就是将SIGINT
发送到进程中不屏蔽信号的一个线程。信号可以被处理或忽略。如果程序确实处理
Ctrl+C
,通常的行为是自我终止,但同样,它可以用于其他任何事情。在您的情况下,一个线程正在接收
SIGINT
,该线程可能会杀死自己,但不会杀死其他线程。Well, the only thing that
Ctrl + C
does is sendingSIGINT
to one thread in the process that is not masking the signal. Signals can be handled or ignored.If the program does handle
Ctrl+C
, the usual behavior is self-termination, but once again, it could be used for anything else.In your case,
SIGINT
is being received by one thread, which probably does kill itself, but does not kill the others.在使用 NPTL 线程的 Linux 2.6 下:我假设该进程使用默认信号处理程序,或在其中调用 exit():是的。 C 库 exit() 调用映射到 exit_group 系统调用,该调用立即退出所有线程;默认信号处理程序调用此或类似的东西。
在使用 Linuxthreads 的 Linux 2.4 下(或者如果您的应用程序出于某种奇怪的原因仍然使用 Linuxthreads,则使用 2.6):不一定。
Linuxthreads 库使用clone() 实现线程,创建一个恰好与父进程共享其地址空间的新进程。当父母去世时,它不一定会死亡。为了解决这个问题,pthreads 创建了一个“主线程”。该主线程执行各种操作,其中之一是尝试确保当进程退出时(无论出于何种原因)所有线程都被杀死。
因此,如果您使用 Linuxthreads,可能不会。
其他线程可能不会立即退出,或者根本不会退出。
但是,无论您使用什么线程库,分叉的子进程都会继续(如果它们仍在同一进程组中,它们可能会收到信号,但可以自由地忽略它)
Under Linux 2.6 using NPTL threads: I am assuming that the process uses the default signal handler, or calls exit() in it: Yes it does. The C library exit() call maps to the exit_group system call which exits all the threads immediately; the default signal handler calls this or something similar.
Under Linux 2.4 using Linuxthreads (or using 2.6 if your app still uses Linuxthreads for some weird reason): Not necessarily.
The Linuxthreads library implements threads using clone(), creating a new process which happens to share its address-space with the parent. This does not necessarily die when the parent dies. To fix this, there is a "master thread" which pthreads creates. This master thread does various things, one of them is to try to ensure that all the threads get killed when the process exits (for whatever reason).
So if you're using Linuxthreads, possibly not.
The other threads might not exit immediately, or indeed at all.
However, no matter what thread library you use, forked child processes will continue (they might receive the signal if they are still in the same process-group, but can freely ignore it)