会在哪些情况下向linux进程间事件发送发送SIGKILL信号

他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)一些常用的kill信号的对比和总结_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
一些常用的kill信号的对比和总结
&&一些常用的kill信号的对比和总结
阅读已结束,下载本文需要
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢系统什么时候发送SIGKILL信号_百度知道
系统什么时候发送SIGKILL信号
我有更好的答案
你在进程中如果设置捕获这2个信号就可以监测到系统关机或重启,会发送2个信号:先发送SIGTERM信号,再发送SIGKILL信号。。会的
采纳率:87%
为您推荐:
其他类似问题
信号的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。向进程发送信号:kill、killall 和 top
向进程发送信号:kill、killall 和 topkill、killall这两个命令是用来向进程发送信号的。kill 命令需要进程号作为参数,而 killall 需要进程名称。 另外,还可以在这两个命令后附加要发送信号序号作为参数。默认情况下,它们都向相关进程发送信号 15 (TERM)。例如,如果您想要终止 PID 为 785 的进程,请输入以下命令:$ kill 785如果您要向它发送信号 19 (STOP),请输入:$ kill -19 785假设您知道想要终止的进程的命令名称。您可以通过该名称来终止它,而不用再使用 ps 找出该进程的进程号:$ killall -9 mozilla无论如何,您只能终止您自己的进程(除非您是 root),因此当您运行多用户系统时您不必担心您“邻居”的进程,它们不会受到影响。综合 ps 和 kill:toptop 程序同时完成 ps 和 kill 的功能,并能用于实时监控进程的 CPU 和内存使用状况、执行时间等等。如所示。图 6.1. 用 top 监控进程top 工具完全使用键盘控制。按下 h 就能访问其帮助信息。其最有用的命令如下: k:用于向某进程发送信号。top 随后会询问您进程的 PID 以及要发送的信号序号或信号名称(默认为 TERM,即信号 15);M:按照内存使用情况(%MEM 列)对进程排序;P:按照 CPU 使用时间(默认为 %CPU 列)对进程排序; u:显示给定用户的进程。top 会向您询问是哪个用户。请输入该用户的名称,而不是他的 UID。如果您没有输入任何名称,将显示所有进程; i:默认显示所有进程,包括睡眠进程。而这条命令确保只显示当前正在运行的进程(STAT 列为 R (运行)的那些进程)。再次输入该命令将返回显示所有进程。r:改变选中进程的优先级别。博客访问: 443691
博文数量: 36
博客积分: 330
博客等级: 一等列兵
技术积分: 3002
注册时间:
java开发工程师,专注于内核源码,算法,数据结构。
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
kill信号涉及到的系统调用有sys_kill,sys_tkill,sys_tgkill函数等,sys_kill的处理的机制有以下这么几种:
pid>0信号被发送到pid的那个进程上。
pid=0信号被发送到当前调用sys_kill操作的进程组上。
pid=-1信号被发送给所有进程。
pid<-1信号被发送到-pid的线程组上。
这里说下sys_kill函数的过程,流程图如下:
& &&从上图中可以看出,sys_kill系统调用最终还是调用了group_send_sig_info,这个是线程组通知的函数,也就是信号进入公共信号队列,kill_pgrp_info就是递归某个进程组,然后给进程组中的每个线程组发送信号。
& &&分析一下kill_something_info函数:
static int kill_something_info(int sig, struct siginfo *info, pid_t pid){
&&&&&&&&&&&&int ret;
&&&&&&&&&&&&if (pid > 0) { //当pid大于0的时候,发送给pid的那个进程
&&&&&&&&&&&&&&&&&&&&rcu_read_lock();
&&&&&&&&&&&&&&&&&&&&ret = kill_pid_info(sig, info, find_vpid(pid));
&&&&&&&&&&&&&&&&&&&&rcu_read_unlock();
&&&&&&&&&&&&&&&&&&&&return ret;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&read_lock(&tasklist_lock);
&&&&&&&&&&&&if (pid != -1) { //如果不是-1的时候,也就是发送给进程组,如果0就是当前进程组,不是0也不是-1就是发送给-pid的进程组
&&&&&&&&&&&&&&&&&&&&ret = __kill_pgrp_info(sig, info,pid ? find_vpid(-pid) : task_pgrp(current));
&&&&&&&&&&&&} else { //发送给所有进程
&&&&&&&&&&&&&&&&&&&&int retval = 0, count = 0;
&&&&&&&&&&&&&&&&&&&&struct task_struct * p;
&&&&&&&&&&&&&&&&&&&&for_each_process(p) { //递归从init_task
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if (task_pid_vnr(p) > 1 &&!same_thread_group(p, current)) {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&int err = group_send_sig_info(sig, info, p);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&++count;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if (err != -EPERM)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&retval = err;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&ret = count ? retval : -ESRCH;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&read_unlock(&tasklist_lock);
&&&&&&&&return ret;
& &&实际发送信号的过程就是在对应的进程的pending队列,写入信号的相关信息,这个过程在send_signal函数中,比较重要的函数就是prepare_signal函数和complete_signal函数,prepare_signal函数,在发送信号的过程中,如果这个进程收到了stop类的信号,那么就需要移除pending队列中的SIGCONT信号,如果收到了SIGCONT信号,那么group
stop过程就应该停止,移除pending队列中的stop类信号,同时让那个暂停的进程重新开始运行。
if (unlikely(signal->flags & SIGNAL_GROUP_EXIT)) { //处于group exit过程,参考 内核signal_struct中notify_count变量的作用
&&&&&&&&} else if (sig_kernel_stop(sig)) { //如果是stop类信号,移除SIGCONT信号
&&&&&&&&&&&&rm_from_queue(sigmask(SIGCONT), &signal->shared_pending);
&&&&&&&&&&&&t = p;
&&&&&&&&&&&&do {
&&&&&&&&&&&&&&&&&&&&rm_from_queue(sigmask(SIGCONT), &t->pending);
&&&&&&&&&&&&} while_each_thread(p, t);
&&&&&&&&} else if (sig == SIGCONT) { //如果是SIGCONT信号,移除stop信号,同时使那个进程重新开始执行
&&&&&&&&&&&&unsigned int why;
&&&&&&&&&&&&rm_from_queue(SIG_KERNEL_STOP_MASK, &signal->shared_pending);
&&&&&&&&&&&&t = p;
&&&&&&&&&&&&do {
&&&&&&&&&&&&&&&&&&&&unsigned int state;
&&&&&&&&&&&&&&&&&&&&rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
&&&&&&&&&&&&&&&&&&&&state = __TASK_STOPPED;
&&&&&&&&&&&&&&&&&&&&if (sig_user_defined(t, SIGCONT) && !sigismember(&t->blocked, SIGCONT)) {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&set_tsk_thread_flag(t, TIF_SIGPENDING);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&state |= TASK_INTERRUPTIBLE;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&wake_up_state(t, state);
&&&&&&&&&&&&&&&&} while_each_thread(p, t);
& & &对于那种SIGKILL,SIGSTOP这种信号,在调试器发送stop信号的时候,调用ptrace的attach操作的时候发送的信号是SEND_SIG_FORCED的,在处理信号的时候,在prepare_signal函数之后,会判断如果是SEND_SIG_FORCED,那么就不记录那个siginfo了。
complete_signal函数的作用就是找到线程组中的一个线程,唤醒他,设置TIF_SIGPENDING来处理信号。这个筛选线程的处理逻辑在want_signal中
static inline int wants_signal(int sig, struct task_struct *p)
&&&&&&&&&&&&&&&&if (sigismember(&p->blocked, sig)) //如果当前信号被block,就说明这个线程不适合处理信号
&&&&&&&&&&&&&&&&&&&&&&&&return 0;
&&&&&&&&&&&&&&&&if (p->flags & PF_EXITING) //如果当前进程正在退出,说明这个线程不能处理信号
&&&&&&&&&&&&&&&&&&&&&&&&return 0;
&&&&&&&&&&&&&&&&if (sig == SIGKILL) //如果是SIGKILL信号,就必须处理信号
&&&&&&&&&&&&&&&&&&&&&&&&return 1;
&&&&&&&&&&&&&&&&if (task_is_stopped_or_traced(p)) //如果当前进程处于暂停或者调试状态,说明这个线程不适合处理信号
&&&&&&&&&&&&&&&&&&&&&&&&return 0;
&&&&&&&&&&&&&&&&return task_curr(p) || !signal_pending(p); //如果是发送给当前线程的信号或者这个线程上没有信号需要处理,那么这个线程就应该处理这个信号
complete_signal的逻辑 &kernel/signal.c
static void complete_signal(int sig, struct task_struct *p, int group)
&&&&&&&&&&&&&&&&struct signal_struct *signal = p->signal;
&&&&&&&&&&&&&&&&struct task_struct *t;
&&&&&&&&&&&&&&&&if (wants_signal(sig, p)) //判断目标线程是否可以发送信号
&&&&&&&&&&&&&&&&&&&&&&&&t = p;
&&&&&&&&&&&&&&&&else if (!group || thread_group_empty(p)) //如果目标线程不可以发送信号,在若这个信号是tkill过来的或者线程组中没有其他的线程,那么只能什么都不唤醒了。
&&&&&&&&&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&&&&&else { //递归线程组,找到一个合适的线程
&&&&&&&&&&&&&&&&&&&&&&&&t = signal->curr_target;
&&&&&&&&&&&&&&&&&&&&&&&&while (!wants_signal(sig, t)) {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&t = next_thread(t);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if (t == signal->curr_target)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&&&&&&&&&signal->curr_target = t;
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&if (sig_fatal(p, sig) &&!(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) &&!sigismember(&t->real_blocked, sig) &&
&&&&&&&&&&&&&&&&(sig == SIGKILL || !t->ptrace)) {
&&&&&&&&&&&&&&&&&&&&&&&&if (!sig_kernel_coredump(sig)) {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&signal->flags = SIGNAL_GROUP_EXIT;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&signal->group_exit_code = sig;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&signal->group_stop_count = 0;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&t = p;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&do {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sigaddset(&t->pending.signal, SIGKILL);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&signal_wake_up(t, 1);
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&} while_each_thread(p, t);
&&&&&&&&&&&&&&&&&&&&&&&&return;
&&&&&&&&&&&&&&&&}
&&&&&&&&signal_wake_up(t, sig == SIGKILL); //最后唤醒指定的线程,设置TIF_SIGPENDING
&&&&&&&&return;
这里进程调度的代码不熟悉,不多做分析,等看懂了进程调用的代码再来仔细分析。
& & &kill信号发送给线程组,因为线程是共享主线程的signal结构的,发送给主线程的want_signal如果为false,那么是由那个线程组中其他的一个线程负责处理这个信号的,也就是说这种线程组group
kill,只需要线程组中有一个线程来处理信号即可,其他非线程组kill另当别论。
阅读(5207) | 评论(0) | 转发(6) |
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 linux 向进程发送信号 的文章

 

随机推荐