Linux IPC 进程间通信——信号signal

目录

一、相关函数分析

signal函数

 kill函数

raise函数

pause函数

二、实例展示

实例1,signal&alarm&pause

实例2,signal&kill&raise


首先认识几个相关的信号函数,signal、kill、raise、pause。

一、相关函数分析

signal函数

void (*signal(int signum,void(* handler)(int)))(int);

        说明:当前进程收到signum对应的信号之后,会执行handler指向的函数。
        其中signum有

#define SIGHUP         1    /* Hangup (POSIX).  */
#define SIGINT         2    /* Interrupt (ANSI).  */
#define SIGQUIT         3    /* Quit (POSIX).  */
#define SIGILL         4    /* Illegal instruction (ANSI).  */
#define SIGTRAP         5    /* Trace trap (POSIX).  */
#define SIGIOT         6    /* IOT trap (4.2 BSD).  */
#define SIGABRT         SIGIOT    /* Abort (ANSI).  */
#define SIGEMT         7
#define SIGFPE         8    /* Floating-point exception (ANSI).  */
#define SIGKILL         9    /* Kill, unblockable (POSIX).  */
#define SIGBUS        10    /* BUS error (4.2 BSD).  */
#define SIGSEGV        11    /* Segmentation violation (ANSI).  */
#define SIGSYS        12
#define SIGPIPE        13    /* Broken pipe (POSIX).  */
#define SIGALRM        14    /* Alarm clock (POSIX).  */
#define SIGTERM        15    /* Termination (ANSI).  */
#define SIGUSR1        16    /* User-defined signal 1 (POSIX).  */
#define SIGUSR2        17    /* User-defined signal 2 (POSIX).  */
#define SIGCHLD        18    /* Child status has changed (POSIX).  */
#define SIGCLD        SIGCHLD    /* Same as SIGCHLD (System V).  */
#define SIGPWR        19    /* Power failure restart (System V).  */
#define SIGWINCH    20    /* Window size change (4.3 BSD, Sun).  */
#define SIGURG        21    /* Urgent condition on socket (4.2 BSD).  */
#define SIGIO        22    /* I/O now possible (4.2 BSD).  */
#define SIGPOLL        SIGIO    /* Pollable event occurred (System V).  */
#define SIGSTOP        23    /* Stop, unblockable (POSIX).  */
#define SIGTSTP        24    /* Keyboard stop (POSIX).  */
#define SIGCONT        25    /* Continue (POSIX).  */
#define SIGTTIN        26    /* Background read from tty (POSIX).  */
#define SIGTTOU        27    /* Background write to tty (POSIX).  */
#define SIGVTALRM    28    /* Virtual alarm clock (4.2 BSD).  */
#define SIGPROF        29    /* Profiling alarm clock (4.2 BSD).  */
#define SIGXCPU        30    /* CPU limit exceeded (4.2 BSD).  */
#define SIGXFSZ        31    /* File size limit exceeded (4.2 BSD).  */

        如果handler不是函数指针,则必须是SIG_IGN(忽略当前的信号)、SIG_DFL(将参数指定的信号重新设为系统预设的信号处理方式)。
        信号发生之后会跳到指定的handler处理函数,系统这时候相当于把signum对应的默认处理方式替换为用户指定的处理方式,等执行完用户自定的处理方式之后,系统会把它替换回来。如果想替换系统原来的默认处理方式可以参考函数sigaction

 kill函数

int kill(pid_t pid,int signum);

        说明:该函数用于向指定的进程pid,发送sig信号编号。
        其中参数pid有以下情景:

pid>0指定的进程号
pid=0将信号传给与当前进程相同进程组的所有进程
pid=-1将信号传递给系统的所有进程
pid<-1将信号传递给进程组识别码为PID绝对值的所有进程

        sig参考上面的signal对应的signum。

raise函数

int raise (int signum);

        说明:向同一进程发送sig编号的信号。它与kill的区别是,raise不可以指定pid,只能指向当前的进程。

pause函数

int pause(void);

        说明:让当前进程暂停(进入睡眠模式)直到被信号中断。

二、实例展示

实例1,signal&alarm&pause

signal注册一个SIG_ALARM处理函数,pause暂停程序返回,等signal处理完后,继续执行

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


void alarmHandler(){
	printf("alarmHandler func.\n");
}

int main(){
	int ret;
	
	printf("listen signal...\n");
	signal(SIGALRM, &alarmHandler);

	ret = alarm(5);
	pause();// wait until signal arrived
	printf("ok ret is %d\n", ret);
	return 0;
}

运行结果:

listen signal...
alarmHandler func.
ok ret is 0

实例2,signal&kill&raise

        实例展示kill和raise的使用,通过fork创建一个子进程,父进程用raise发送信号给自己,子进程用kill发送给自己或同组的其它进程,同事我们可以看到子进程继承了父进程的signal函数。

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

void my_func(int sig_no){
	if(sig_no == SIGINT){
		printf("I have get SIGINT pid=%d\n", getpid());
	}else if(sig_no == SIGQUIT){
		printf("I have get SIGQUIT pid=%d\n", getpid());
	}
}

int main(){
	pid_t pid, ppid, cpid;

	
	printf("Waitting for SIGINT or SIGQUIT\n");
	signal(SIGINT, my_func);
	signal(SIGQUIT, my_func);

	pid = fork();
	if (pid > 0)
	{
		ppid = getpid();
		printf("parent process pid=%d\n", ppid);
		raise(SIGQUIT);
	}else if (pid == 0)
	{
		cpid = getpid();
		printf("chlid process pid=%d\n", cpid);
		sleep(1);
		kill(0, SIGINT);
		//kill(ppid, SIGINT);
		//kill(cpid, SIGINT);
		//raise(SIGQUIT);
	}
	pause();
	exit(0);
	
}

运行结果

Waitting for SIGINT or SIGQUIT
parent process pid=111605
I have get SIGQUIT pid=111605
chlid process pid=111606
I have get SIGINT pid=111606
I have get SIGINT pid=111605

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值