【linux高级环境编程学习笔记二】信号通信

今天学习了进程间通信的第二种方式,使用信号进行通信。

 

一 信号类型

linux中共有31种信号类型,常见的几种信号类型如下所示:


SIGHUP:从终端上发出的结束信号

SIGINT:来自健盘的中断信号(ctrl+c)

SIGKILL:该信号结束接收信号的进程

SIGTERM: kill命令发出的信号

SIGCHLO:标识子进程停止或结束的信号

SIGSTOP:来自健盘(ctrl+z)或调试程序的停止执行信号

 

二 常见信号处理方式

当某信号出现时,通常会采用以下几种常见的处理方式:

1. 忽略此信号

大多数都是采用这种信号处理方式,但是有两种信号不能被忽略,SIGKILL SIGSTOP。

 

2.执行系统默认的动作

系统对于大多数信号采取的动作是终止该进程。

 

3.执行用户希望的动作

通知内核,当某种信号出现是,调用一个用户函数,在这个用户函数中,执行用户希望的动作。

 

三 信号发送函数

在linux中可以使用以下几个函数向某进程发送信号:

1. kill

int kill(pid_t pid, int signo)

pid参数为接受信号进程的pid,signo为需要发送信号的类型。

 

2. raise

int raise(int signo)

对比raise和kill函数的原型可以看出,kill能向所有进程发送信号,而raise只能向本进程发送信号。

 

3. kill命令

关于kill命令的使用方法,可以在终端里面执行man kill查看,在此略过。

 

4. alarm函数

unsigned int alarm(unsigned int seconds)

在seconds秒之后,会向本进程发送SIGARM信号

 

四 信号处理函数

当某种信号出现时,若希望能执行用户所希望的动作,则需要使用signal函数来制定信号处理函数。signal函数的函数原型为void*(signal(int signo, void*(func(int))))(int),函数原型看起来复杂,使用起来却比较简单,在后面会有例子。

func的可能的值如下:

1. SIG_IGN: 忽略此信号;

2. SIG_DFL: 按系统默认的动作去处理;

3. 信号处理函数名:使用该函数去处理。

 

此外,pause函数是使进程挂起,直至捕捉到一个信号,并且只有执行了一个信号处理函数之后,挂起才结束。

 

五 例子

#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
void my_function(int signalno)
{
	switch(signalno)
	{
		case SIGINT: printf("Catch a SIGINT signal\n");break;
		case SIGQUIT: printf("Catch a SIGQUIT signal\n");break;
		default: printf("error!\n");break;
	}

}
int main(int args, char* argv[])
{
	printf("Waiting for signal SIGINT OR SIGQUIT\n");

	signal(SIGINT,my_function);
	signal(SIGQUIT,my_function);

	pause();
	exit(0);
	
}

使用ps -aux查看本进程pid之后,再用kill命令发送信号:

kill -SIGQUIT 13253

运行结果如下:

Waiting for signal SIGINT OR SIGQUIT
Catch a SIGQUIT signal

 

欢迎关注新浪微博:ThreadX

共同学习,共同进步!


 

 

 

 

 

 

你可能感兴趣的:(linux,进程通信,信号)