Head First C 学习日志 第十章 进程间通信 捕捉信号

北战南征 提交于 2019-12-03 05:15:48

Head First C 第十章 进程间通信 捕捉信号

关于信号

信号是操作系统控制程序的方式,举个栗子,操作系统在看到用户输入了Ctrl+C时,就会向程序发送中断信号。 信号映射表

信号 处理函数
SIGURG 不做事情
SIGINT 调用exit()

捕捉信号然后运行自己的代码

有时候你希望别人打断你的程序时运行自己的代码。假设进程打开了一些文件或网络连接,你希望在退出之前把它们关闭,并且做一些清理工作。在这里引入sigaction结构。 sigaction是一个函数包装器 sigaction是一个结构体,它有一个函数指针,siagction告诉操作系统进程收到某个信号时该调用哪个函数

sigaction的创建方法如下
	struct sigaction action;
	action.sa_handler = handler;
	sigemptyset(&action.sa_mask);
	action.sa_flag = 0;

sigemptyset用于设置信号,在信号被使用前必须调用sigemptysetsigfillsetsigemptyset在man中的函数原型和解释是:

	int sigemptyset(sigset_t *set);

The sigemptyset() function initializes a signal set to be empty.

将信号初始化设置为空。 处理器必须接收信号参数 信号是一个整型值,如果你创建了一个自定义处理函数,就需要接收一个整型参数:

	void diediedie(int sig) {
	  puts("Goodbye cruel world...\n");
	  exit(1);
	}
用sigaction()注册sigaction

创建sigaction以后,需要用sigaction()函数注册,使操作系统知道它的存在。

	int sigaction(int sig, const struct sigaction *restrict act, struct sigaction *restrict oact);

sigaction()函数接收3个参数,信号,动作,旧动作(可以传NULL)。

将创建和初始化封装成一个函数
	int catch_signal(int sig, void (*handler)(int)) {
	struct sigaction action;
	action.sa_handler = handler;
	sigemptyset(&action.sa_mask);
	action.sa_flags = 0;
	return sigaction(sig, &action, NULL);
}

这样只要把信号和处理器传给catch_signal()函数,就可以设置信号处理器了。

给进程发送信号

用kill命令发送信号

运行程序后,可以使用Ctrl+C发送一个中断信号,如果想发送其他信号,可以用在终端下用kill命令,格式为kill -信号 进程号 kill -INT 1739的效果和Ctrl+C一样,都是发送中断信号。

在进程内发送信号

在进程内可以使用raise()函数向自己发送信号。 通常会在自定义的信号处理器中使用raise(),这样程序就能在接收到低级别的信号时引发更高级别的信号,这叫做信号升级

例程代码

signal handler sample

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!