IPC-Signal 信号

本文介绍了Linux系统中进程间通信的信号机制,包括信号的定义、常用信号常量、信号的简单使用以及通过sigset和signal函数处理信号的区别。示例展示了如何设置信号处理函数并使用kill命令发送信号,以及信号在程序中的响应情况。
摘要由CSDN通过智能技术生成

Linux和类Linux系统下进程间通信(Inter-Process Communication, IPC)有很多种方式

  • 套接字(socket)
  • 共享内存(shared memory)
  • 管道(pipe)
  • 消息队列(message queue)

信号,是Linux中向进程发送的消息,即通过软中断的方式来响应这个信号,触发一些事先指定或特定的事件。

进程之间可以互相通过系统调用kill来发送信号,内核也可以因为内部事件而给进程发送信号,通知进程。

1. linux定义的信号量

/usr/include/x86_64-linux-gnu//bits/signum.h下面

cat /usr/include/x86_64-linux-gnu//bits/signum.h 
#ifndef _BITS_SIGNUM_H
#define _BITS_SIGNUM_H 1

#ifndef _SIGNAL_H
#error "Never include <bits/signum.h> directly; use <signal.h> instead."
#endif

#include <bits/signum-generic.h>

/* Adjustments and additions to the signal number constants for
   most Linux systems.  */

#define	SIGSTKFLT	16	/* Stack fault (obsolete).  */
#define	SIGPWR		30	/* Power failure imminent.  */

#undef	SIGBUS
#define	SIGBUS		 7
#undef	SIGUSR1
#define	SIGUSR1		10
#undef	SIGUSR2
#define	SIGUSR2		12
#undef	SIGCHLD
#define	SIGCHLD		17
#undef	SIGCONT
#define	SIGCONT		18
#undef	SIGSTOP
#define	SIGSTOP		19
#undef	SIGTSTP
#define	SIGTSTP		20
#undef	SIGURG
#define	SIGURG		23
#undef	SIGPOLL
#define	SIGPOLL		29
#undef	SIGSYS
#define SIGSYS		31

#undef	__SIGRTMAX
#define __SIGRTMAX	64

#endif	/* <signal.h> included.  */

或者输入 kill -l 能够查看系统所支持的信号,每一个信号的名字都是以SIG开头

wanglei@wanglei-PC:~/ccode$ kill -l
 1) SIGHUP	     2) SIGINT	     3) SIGQUIT	     4) SIGILL	     5) SIGTRAP
 6) SIGABRT	     7) SIGBUS	     8) SIGFPE	     9) SIGKILL	    10) SIGUSR1
11) SIGSEGV	    12) SIGUSR2	    13) SIGPIPE	    14) SIGALRM	    15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD	    18) SIGCONT	    19) SIGSTOP	    20) SIGTSTP
21) SIGTTIN  	22) SIGTTOU	    23) SIGURG	    24) SIGXCPU	    25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	    28) SIGWINCH	29) SIGIO	    30) SIGPWR
31) SIGSYS	    34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

2. 信号的简单使用

获取自身的Pid

#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);

2.1 使用sigset接收信号

函数原型

#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t sigset(int sig,sighandler_t disp);

测试案例

#include <stdio.h>
#include <signal.h>

void handler();

int main(int argc, char ** argv)
{
    sigset( SIGUSR1  , handler );
    sigset( SIGUSR2  , handler );
    printf( "Process_pid=[%d]\n", getpid() );
    while(1);
    return 0;
}

void handler(int signo)
{
    switch(signo) {
    case SIGUSR1: //处理信号 SIGUSR1
        printf("SIGUSR1 received...\n");
        break;
    case SIGUSR2: //处理信号 SIGUSR2
        printf("SIGUSR2 received...\n");
        break;
    default:
        printf("Other signal...\n");
        break;
    }
}

然后使用kill命令

wanglei@wanglei-PC:~$ kill -USR1 7724
wanglei@wanglei-PC:~$ kill -USR2 7724
wanglei@wanglei-PC:~$ kill -10 7724
wanglei@wanglei-PC:~$ kill -12 7724

程序那边就会收到

wanglei@wanglei-PC:~/ccode$ ./a.out 
Process_pid=[7724]
SIGUSR1 received...
SIGUSR2 received...
SIGUSR1 received...
SIGUSR2 received...
^C

2.2 使用signal接收信号

函数原型

#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int)

关于参数

  • sig – 在信号处理程序中作为变量使用的信号码

    信号
    SIGABRT(Signal Abort) 程序异常终止。
    SIGFPE(Signal Floating-Point Exception) 算术运算出错,如除数为 0 或溢出(不一定是浮点运算)。
    SIGILL(Signal Illegal Instruction) 非法函数映象,如非法指令,通常是由于代码中的某个变体或者尝试执行数据导致的。
    SIGINT(Signal Interrupt) 中断信号,如 ctrl-C,通常由用户生成。
    SIGSEGV(Signal Segmentation Violation) 非法访问存储器,如访问不存在的内存单元。
    SIGTERM(Signal Terminate) 发送给本程序的终止请求信号。
  • func – 一个指向函数的指针。它可以是一个由程序定义的函数,也可以是预定义函数

    函数说明
    SIG_IGN忽视信号。
    SIG_DFL默认的信号处理程序。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

void sighandler(int);

int main()
{
   signal(SIGINT, sighandler);

   while(1) 
   {
      printf("开始休眠一秒钟...\n");
      sleep(1);
   }

   return(0);
}

void sighandler(int signum)
{
   printf("捕获信号 %d,跳出...\n", signum);
   exit(1);
}

另外开一个窗口,发送信号

wanglei@wanglei-PC:~$ kill -10 10603

wanglei@wanglei-PC:~$ kill -12 10654

程序那边

wanglei@wanglei-PC:~/ccode$ ./a.out 
pid====>10603
开始休眠一秒钟...
开始休眠一秒钟...
开始休眠一秒钟...
用户定义信号 1

wanglei@wanglei-PC:~/ccode$ ./a.out 
pid====>10654
开始休眠一秒钟...
开始休眠一秒钟...
用户定义信号 2

3. sigset 与 signal的区别

sigset 系统调用制定一个持久的信号处理函数,在信号发生时,不会被重置为默认处理动作。

signal 调用使用的是默认的信号处理函数处理了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值