上文为大家简单的介绍了共享内存的方式进行两个不同的进程间通信,本文为大家介绍应用场景更加多的信号的进程间的通信方式,信号更多的应用在异步通信,两个没有任何关系的进程之间更多的通过信号来控制彼此,也是我们平常开发应用当中比较常见的一种通信方式。
- 同步通信:按照指定的顺序进行运行
- 异步通信:一种随机事件,在程序编写阶段不能够确定事件发生的时机
如同字面意思,信号的应用应该在某一个进程当中进行发送信号的接口指令,在另一个进程进行接受信号的接口指令。
框架:注册一个信号-(接收方)---》发送信号----》处理(注册的信号处理函数)
1.接收信号signal
sighandler_t signal(int signum, sighandler_t handler);
- 功能:注册一个信号并设置信号的处理方式
- 参数:
- signum:信号的编号
- handler:信号的处理方式
- 缺省(SIG_DFL):按照操作系统默认方式处理信号
- 忽略(SIG_IGN):不响应信号
- 捕获(hander):按照用户自定义的方式处理信号,(handler为函数的自定义函数的处理地址(typedef void (*sighandler_t)(int);))
- 返回值:
- 成功返回上一次注册的信号处理函数
- 失败返回SIG_ERR
代码示例:
#include <stdio.h> #include <string.h> #include <signal.h> #include <unistd.h> void handler(int signo) { printf("%d signal coming.\n", signo); } int main(int argc, const char *argv[]) { signal(2, SIG_DFL); // signal(2, SIG_IGN) // signal(2, handler); while(1) { printf("i am process.\n"); sleep(1); } return 0; }
以上signal的调用为三种方式的调用第一种为系统默认,在系统外面运行时自己输入ctrl+c强制退出面对设置的2号信号来临时,进程会按照系统默认方式处理2号信号,也就是会正常退出,而在第二种方式为忽略信号的来临,当代码运行起来在终端输入ctrl+c的时候,进程运行不会结束,需要运行外部的文件的命令kill -9才可以强制结束,而第三种为自定义处理方式,在终端输入ctrl+c的时候程序终端会显示2 signal coming且进程不会退出。
2.发送信号kill
int kill(pid_t pid, int sig);
- 功能:给进程发送信号
- 参数:
- pid:要发送信号给到次进程的ID号
- sig:信号的ID号
- 返回值:
- 成功返回0
- 失败返回-1
代码示例:
void handle(int num) { printf("father 2\n"); sleep(1); } int main(int argc, const char *argv[]) { pid_t pid = fork(); if(pid > 0) { int i = 3; while(i--) { printf("father 1\n"); sleep(1); } kill(pid, 10); while(1) { printf("father 3\n"); sleep(1); } } else if(0 == pid) { int i = 5; signal(10, handle); while(1) { printf("son 1\n"); sleep(1); } } else { perror("fail to fork"); return -1; } return 0; }
3.发送信号raise
int raise(int sig);
- 功能: 给调用该函数的进程发送sig信号(同kill,但是kill是指定的进程,而raise给自己这个进程发信号,但是同样不要忽略signal创建信号量的处理方式才可以使用)
代码示例:
void handler(int signum) { int i = 3; while(i--) { printf("-------------\n"); } } int main(int argc, const char *argv[]) { signal(12, handler); int i = 5; while(i--) { printf("+++++++++++++=\n"); } raise(12); i = 5; while(i--) { printf("!!!!!!!!!!!!\n"); } printf("end\n"); return 0; }
以上就是进程间通信,信号的简单的应用,还有类似于pause、alarm等等发送信号的函数,但是应用最多的还是kill结合以上的应用再结合进程线程,我们就可以实现之前进程线程的通信升级方法,可以实现信号管道间的通信方式实现全双工的升级等等,综合这些内容,我们如果能够全部掌握,那么进程和线程的基本掌握就可以说很好了,接下来,我们将进行网络的章节进行学习,谢谢大家!