【Linux】进程间通信:信号

本文介绍了信号在软件中的作用,作为异步通信方式,用于进程间交互和通知系统事件。文章详细讲解了信号的处理方式,包括忽略、捕获和执行默认操作,并列举了多种信号类型。此外,还讨论了信号相关的API,如signal、kill、raise、alarm和pause的功能和用法。最后,通过示例展示了如何使用信号回收僵尸进程以及接收并响应特定信号。
摘要由CSDN通过智能技术生成

目录

1、信号的概念

2、进程对信号的处理方式

3、信号有哪些:kill -l

4、信号相关API

4.1 signal

4.2 kill

4.3 raise 

4.4 alarm

4.5 pause

5、应用程序:用信号回收僵尸进程

6、应用程序:接收到信号后输出一句话代表接收到信号


1、信号的概念

1、信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
2、信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来 通知 用户空间进程发生了哪些系统事件
3、如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它
4、如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程

2、进程对信号的处理方式

1、忽略信号

对信号不做处理,但是有两个信号是不能忽略:  9)SIGKILL   19)SIGSTOP

2、捕获信号

自定义信号处理函数,当信号发生的时候,立即执行自定义信号处理函数。

3、执行缺省操作(执行默认操作)

每个信号都有自己默认的处理函数。

3、信号有哪些: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    

4、信号相关API

4.1 signal

sighandler_t signal(int signum, sighandler_t handler);
/*
功能:捕获信号,为信号注册处理函数;
头文件:
       #include <signal.h>
参数:
    @signum:指定要捕获的信号;可以填信号编号,也可以填对应的宏;
	@handler:
		1.SIG_IGN:忽略信号;
		2.SIG_DFL:执行默认操作;
		3.函数指针变量,该函数指针能够指向返回值是void类型,且参数列表是int类型的函数。
返回值:
    成功,返回该信号的上一个信号处理函数首地址; 
    失败,返回SIG_ERR,更新errno;		
*/
		

4.2 kill

int kill(pid_t pid, int sig);
/*
功能:发送信号给指定的进程;
头文件:
       #include <sys/types.h>
       #include <signal.h>
参数:
    @pid:指定要发送给哪个进程或者哪个进程组;
		pid > 0, 	将信号发送给指定进程;
		pid == 0, 	将信号发送给当前进程组下的所有进程;
		pid == -1, 	将信号发送给当前进程权限所能发送到的所有进程,除了1号进程.
        pid < -1, 	将进程发送给指定进程组下的所有进程,进程组id == -pid;
	@sig:指定要发送的信号; 62个信号之一
返回值:
    成功,返回0;
	失败,返回-1,更新errno;
*/

4.3 raise 

int raise(int sig);
/*
功能:给自己发送一个信号
	int raise(int sig)  等同于 kill(getpid(), sig)
*/

4.4 alarm

unsigned int alarm(unsigned int seconds);
/*
功能:设置一个定时器,等时间结束后,产生一个14) SIGALRM 时钟信号;
头文件:
       #include <unistd.h>
参数:
    @seconds:设置定时器的时间,以秒为单位;
			seconds == 0,删除定时器,并且不会产生14号信号;
返回值:
    >0, 返回上一个时钟没有走完的时间;
	=0, 没有设置定时器,或者上一次设置的定时器已经走完了;
*/

4.5 pause

int pause(void);
/*
功能:使当前进程阻塞,直到进程收到任意信号,并从信号处理函数中返回;
头文件:
       #include <unistd.h>     
返回值:
    -1,errno == EINTR,pause会一直阻塞,直到进程收到任意信号,并从信号处理函数中返回,解除阻塞;
*/

5、应用程序:用信号回收僵尸进程

        在前面Linux 进程基础5.2.3中,提到了可以用子进程在退出的时候,给父进程发送一个SIGCHLD信号,来回收僵尸进程。

void handler(int sig)
{
	while(waitpid(-1,NULL, WNOHANG) > 0);
	return;
}

int main(int argc, const char *argv[])
{
	sighandler_t s = signal(SIGCHLD, handler);

	int i = 0;
	pid_t pid = 0;
	while(i < 100)
	{
		pid = fork();
		if( 0 == pid) {
			exit(0); 	//直接退出子进程
		}
		i++;
	}

	while(1)
		sleep(1); 		//父进程最后运行到这里

	return 0;
}

6、应用程序:接收到信号后输出一句话代表接收到信号

int main(int argc, char *argv[])
{
	int time_left;
	
	signal(SIGINT, sig_handler);
	signal(SIGQUIT, sig_handler);	

	time_left = sleep(10);
	printf("end sleep ... time_left=%d\n", time_left);
	while(1);
	return 0;
}

void sig_handler(int signo)
{
	if (signo == SIGINT)
		printf("I received a SIGINT!\n");
	if (signo == SIGQUIT)
		printf("I received a SIGQUIT!\n");	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值