信号是什么,有什么用?
例子:今有进程A,B。他们两个负责下载两个不同的文件。A 下到一半了,给 B 发了一个通知:“我下了一半了”,于是 B 就知道,A 下了一半了。
(是什么)定义:信号是进程间异步通信的唯一机制,能够完成进程间消息传递的作用。
如果不清楚什么是异步:
同步:一定要等任务执行完了,得到结果,才执行下一个任务。
异步:不等任务执行完,直接执行下一个任务。
——《Linux C 编程实战》的要点总结
什么是异步通信
例子:异步就是 B 并不知道信号什么时候回来,它在做着自己的事情(下载)。突然来了一个 A 的信号,于是 B 直接处理 A 的信号,然后来了一连串的信号,然而 B 不用等第一个信号处理完了再处理下一个信号,他只管一个个收下来一个个处理。
是什么 定义:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通信方式。
信号怎么用
发信号有哪些方式?
发送信号的主要函数有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort()。
kill 函数有什么用?
发送信号给指定的进程。适合已知 pid 的情况。这里的 kill 并不一定是要杀死进程。
raise 函数有什么用?
向进程本身发送信号。
sigqueue 函数有什么用?
支持信号带参数值。它可以把一个叫做 sigval 的结构体发过去。这个结构体里面可以存一个指针,因此就实现了发数据。
alarm 函数有什么用?
可以设置个定时器,一超时就给进程本身发数据。
setitimer 函数有什么用?
也能定时,但是更复杂。比如它支持三种类型的定时器。这里不赘述。
abort 函数有什么用?
如果目标进程设置了 SIGABRT(当调用abort函数或发生用户异常终止时,会发出 SIGABRT 信号),会解除 SIGABRT 的阻塞,然后向调用进程发送该信号。让其异常退出。
怎么接受和处理信号?
C 库函数 void (signal(int sig, void (func)(int)))(int) 设置一个函数来处理信号,即带有 sig 参数的信号处理程序。
这个函数原型看了就头大,我们拆开看看:
void (
*signal(
int sig,
void (*func)(int)
)
)
(int)
我们一看其实并不复杂,第一个是你要收的信号,第二个是你要处理这个信号的函数,并且这个处理信号的函数有一个整数的参数。具体用法见:http://www.runoob.com/cprogramming/c-function-signal.html
那么我们来看看具体的例子:
if(signal(SIGPIPE,SIG_IGN) == SIG_ERR)
{
perror("can not catch signal:sigpipe\n");
return -1;
}
这个 SIGPIPE
信号表示通信管道破裂(详见:http://www.veryitman.com/2018/04/15/%E4%B8%8D%E8%AE%A9-SIGPIPE-signal-%E5%A4%AA%E5%9A%A3%E5%BC%A0/)
而这个 SIG_IGN
是 C 库自带的信号处理函数,表示忽略此信号。
最后这个 SIG_ERR
表示 signal 函数遇到错误。
所以这个例子的疑似就是:
- 忽视管道破裂函数。
- 如果忽视失败,就输出
can not catch signal:sigpipe
,并返回 -1 。
参考文献
https://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
kill - End a process or job, or send it a signal - IBM
[settimer()函数和alarm()函数]https://blog.csdn.net/seanyxie/article/details/5669104)
C 库函数 - signal()
Written with StackEdit.