Linux进程通信-信号学习

Linux中一共有32种信号,在/usr/include/bits/signum.h 头文件中可以看到

#define    SIGHUP          1   
#define    SIGINT          2   
#define    SIGQUIT         3   
#define    SIGILL          4   
#define    SIGTRAP         5   
#define    SIGABRT         6   
#define    SIGIOT          6   
#define    SIGBUS          7   
#define    SIGFPE          8   
#define    SIGKILL         9   
#define    SIGUSR1         10   
#define    SIGSEGV         11   
#define    SIGUSR2         12   
#define    SIGPIPE         13   
#define    SIGALRM         14   
#define    SIGTERM         15   
#define    SIGSTKFLT       16   
#define    SIGCLD          SIGCHLD   
#define    SIGCHLD         17   
#define    SIGCONT         18   
#define    SIGSTOP         19   
#define    SIGTSTP         20   
#define    SIGTTIN         21   
#define    SIGTTOU         22   
#define    SIGURG          23   
#define    SIGXCPU         24   
#define    SIGXFSZ         25   
#define    SIGVTALRM       26   
#define    SIGPROF         27   
#define    SIGWINCH        28   
#define    SIGPOLL         SIGIO   
#define    SIGIO           29   
#define    SIGPWR          30   
#define    SIGSYS          31   
#define    SIGUNUSED       31

其中SIGKILL(9)与SIGSTOP(19)是不能捕获的,常用的Ctrl+C 发出的是SIGKILL信号。
子进程退出时会向父进程发出SIGCHLD(17)信号,默认情况下它是被屏蔽的。
SIGSTOP与SIGCONT用来暂停和继续目标进程。
SIGABRT,SIGALRM,SIGFPE,SIGPIPE,SIGINT,SIGHUP,SIGILL,SIGQUIT,SIGSEGV,SIGTERM,SIGUSR1
,SIGUSR2这12种信号,如果在进程中没有对其进行捕获处理的话,进程在收到它们时,会终止,当然还有不可捕获的SIGKILL。

在终端中发送信号用kill命令,格式为 kill 信号 目标进程PID,例如要杀掉1000号进程可以
KILL -9 1000 或者 KILL -kill 1000
缺省信号为SIGTERM,即15。

程序示例:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void signal_handler(int signo)
{
    signal(signo, signal_handler);
    printf("recv signal[%d]\n", signo);
    switch(signo)
    {
        case SIGHUP:
             //终端退出
             printf("Process recieve SIGHUP\n");
             break;       
        case SIGTERM:
            /*程序结束(12)信号, 与SIGKILL不同的是该信号可以被阻塞和 
            处理. 通常用来要求程序自己正常退出. shell命令kill缺省产生这 
            个信号.*/
             printf("do sth....\n");
             printf("Process recieve SIGTERM\n");
             break;
        case SIGKILL:
             printf("Process recieve SIGKILL\n");//发送9信号,程序不会阻塞,立即返回,所以这句话打印不出来
             break;
        case SIGINT:
             //按下ctrl+c产生,程序终止
             printf("Process recieve SIGINT\n");
             break;
        case SIGUSR1:
             printf("Process recieve SIGUSR1\n");
             break;
        default:
             printf("%d signal unregister\n", signo);
             break;
    }
    exit(0);
}

int main(int argc, char const *argv[])
{
    signal(SIGTERM, signal_handler);
    signal(SIGKILL, signal_handler);
    signal(SIGINT, signal_handler);
    signal(SIGUSR1, signal_handler);

    pid_t pid = getpid();
    printf("pid=%d\n",pid);

    while(1)sleep(1);
    return 0;
}

在终端发送kill -2 22910
运行结果:
pid=22910
recv signal[2]
Process recieve SIGINT

其他:

signal 函数比较老了,功能有一些限制,现在常用的是 sigaction
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
第一个参数为目标信号,第二个参数为sigaction结构,内有处理机制,信号掩码,和标志。
其效果与signal版本完全一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值