进程间通信之信号讲解

信号

进程间通信的另外一种方式-----信号



前言

kill -l 查看linux系统中定义的所有信号,程序员是不可以自定义信号

提示:以下是本篇文章正文内容,下面案例可供参考

一、终端shell命令发送信号

1)kill -信号的序号 进程的id
例如 kill -9 20000
kill -KILL 20000
kill -SIGINT 20000

2)killall -信号的序号 进程的名字
ctrl + c默认给当前进程发送了SIGINT信号

二、信号的种类

linux规定的信号绝大部分默认动作都是终止进程,具体如下:

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	总共62个信号

三、相关的接口函数

1.信号的发送

1) 头文件 signal.h
2) int kill(pid_t pid,int sig)
参数:pid --> 你要发送信号的那个进程id
sig --> 你要发送的那个信号的序号

2.捕捉信号并改变信号的响应动作(重点)

1)void (*signal(int sig,void(*func)(int)))(int);
void (函数名(参数1,参数2)(int);
返回值 :函数指针 void(
)(int)
参数 :sig -->你要捕捉的信号的序号或者名字
void(*func)(int) -->你捕捉到信号以后,需要改变的动作就通过这个函数实现
2)注意 : 第一点:有两个信号是不能改变他们的默认动作也不能忽略,SIGKILL和SIGSTOP
第二点:signal函数总共有三种用法
用法一:改变信号的默认动作signal(某个信号,函数);
用法二:忽略信号signal(某个信号,SIG_IGN);忽略信号,信号发送过来以后直接舍弃,左耳进右耳出,当做不存在
用法三:使用信号的默认动作 signal(某个信号,SIG_DFL);

代码如下(示例):

//自定义一个函数实现捕捉到SIGINT信号以后的动作 
void catchint(int sig)
{
	printf("I had catched SIGINT signal! id is : %d\n",sig);
}
int main()
{
	printf("current id : %d\n",getpid());
	//调用signal函数去改变SIGINT信号的默认动作
	//SIGINT默认动作是终止你的程序 
	signal(SIGINT,catchint);
	signal(SIGKILL,catchint); //无效的,SIGKILL和SIGSTOP两个信号是不能改变他们的默认动作 
	signal(SIGBUS,catchint);
	signal(SIGSTOP,catchint);//无效的,SIGKILL和SIGSTOP两个信号是不能改变他们的默认动作 
	signal(SIGHUP,SIG_IGN);   //忽略一号信号   1
	signal(SIGQUIT,SIG_IGN);  //忽略三号信号   3 
	
	while(1){
		printf("I'm running!\n");
		sleep(1);
	}
}

3.另外一组信号的收发函数

一、信号的发送(是kill的升级版,发送信号的时候可以携带额外数据)
int sigqueue(pid_t pid,int sig,const union sigval value);
参数 :value -->发送信号需要携带的额外数据就保存在这个联合体
union sigval {
int sival_int //你要携带的整数
void *sival_ptr ;//你要携带的指针
}

/*
	sigqueue发送信号携带额外数据 
*/ 

int main(int argc,char **argv)
{
	//定义联合体变量存放需要携带的额外数据 
	union sigval myval;
	
	//清空 
	bzero(&myval,sizeof(myval));
	
	//初始化 
	myval.sival_int = 255;
	
	sigqueue(atoi(argv[1]),atoi(argv[2]),myval); 
}

2) 信号的捕捉(是signal的升级版,重点)
int sigaction (int sig,const struct sigaction restrict act,struct sigaction restrict oact );
参数: struct sigaction
{
void(
) (int) sa_handler //函数指针,跟signal的第二个一模一样
sigset_t sa_mask //先不管
int sa_flags //开关,让程序员选择使用哪个函数指针
设置为0表示我要使用 void(
) (int) sa_handler
设置为SA_SIGINFO表示我要使用 void(*) (int, siginfo_t *, void ) sa_sigaction
void(
) (int, siginfo_t *, void ) sa_sigaction //函数指针,当你使用sigqueue携带额外数据的时候就需要使用这个版本
}
提示: void(
) (int, siginfo_t *, void *) 函数指针
参数 : int : 捕捉到的信号的序号
siginfo_t :结构体
{
int si_int ;//存放额外发送过来的那个整数
int *si_ptr;//存放额外发送过来的那个指针
}void : 查不到

/*
void catchint(int sig,siginfo_t *info,  void *arg) 
{
	printf("I caught signal is %d shu ju wei :%d\n",sig,info->si_int);
}
*/

void catchint(int sig)
{
	printf("I use other function, signal is : %d\n",sig);
 } 

int main()
{
	printf("jin cheng id is %d\n",getpid());
	struct sigaction myaction;
#if 0
	//清空 
	bzero(&myaction,sizeof(myaction));
	
	//初始化 
	myaction.sa_flags = SA_SIGINFO;
	myaction.sa_sigaction = catchint;
#else
	//清空 
	bzero(&myaction,sizeof(myaction));
	
	//初始化 
	myaction.sa_flags = 0;
	//myaction.sa_handler = catchint;
	myaction.sa_handler = SIG_IGN; //忽略SIGINT 

#endif
	//你要捕捉的信号
	sigaction(SIGINT,&myaction,NULL); 
	
	//阻塞当前进程等待信号的到来
	pause(); 
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了进程间通信之信号的使用,在本博客之外的文章中另有讲解,希望对大家有所帮助

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值