自学嵌入式第三十一天:Linux系统编程-进程间通信
一、原理
进程间通信:IPC(interprocess communicate);
找一个不同进程共同能访问的位置;
此位置在Linux操作系统;
在Linux内核申请一片区域;
二、管道
1.无名管道
pipe;只能给有亲缘关系的进程通信;
#include<unistd.h>
int pipe(int pipefd[2]);
下标为0的端是读端、下标为1的端是写端;
2.有名管道
fifo;可以给任意单机进程通信
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char*pathname,mode_t mode);
pathname:创建文件的路径;mode:创建文件的权限;
remove();
打开有名管道的open会阻塞;
3.管道
管道是一种半双工通信(可以双向通信,但不能同时通信,在某一时刻只能实现单向通信);
所有的管道都是特殊的文件,不支持定位操作(lseek/fseek);
管道底层是队列;
管道是特殊文件,读写文件IO建议使用(open、read、write、close);如果用fgets等标准IO会进入缓存区;
4.管道的特性
写阻塞:读端存在,一直向管道写,写满64k;
读阻塞:写端存在,读的快;
管道破裂:读端关闭,写管道会管道破裂,会导致写端进程会被系统结束;
read 0:写端写完关闭,管道内数据读完之后继续读,返回值是0(如果用fgets则返回NULL),意味着进程间通信结束;
三、信号
1.中断:cpu在执行任务中,被更高优先级的紧急任务打断,先做更紧急的任务,完成后再回来继续执行;
2.共有64个信号
kill -l 查询这64个信号
1) SIGHUP 终端已经断开;
2) SIGINT 关闭相当于ctrl+c;
3) SIGQUIT 也是退出信号,相当于ctrl+\;
4) SIGILL 在程序越界时系统给程序发的结束信号;
5) SIGTRAP gdb不能跟进汇编里,要访问被保护的系统内核时触发;
6) SIGABRT 内存访问越界触发;
7) SIGBUS 程序错误关闭;
8) SIGFPE 算数运算错误关闭;
9) SIGKILL 强制关闭,高权限;
10) SIGUSR1 由应用层决定,默认关闭,系统预留的可修改的信号;
11) SIGSEGV 段错误;
12) SIGUSR2 由应用层决定,默认关闭,系统预留的可修改的信号;
13) SIGPIPE 管道破裂;
14) SIGALRM 定时器,周期性触发,高精度;
15) SIGTERM 单kill,关闭;
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
man 7 signal 可以查到信号的默认动作是暂停还是关闭等
3.响应:
(1)接收方收到信号结束任务(term);
(2)接收方收到信号忽略(ign);
(3)接收方收到信号终止进程并导出(core);
(4)进程收到信号暂停(stop);
(5)进程收到信号继续(cont);
4.kill
#include<sys/types.h>
#include<signal.h>
int kill (pid_d pid,int sig);
给pid进程发sig信号;
5.signal
type void(*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);
收到信号signum时执行handler函数;
signum:SIGUSR1、SIGUSR2可以供自己随意改;
handler:SIG_IGN忽略、SIG_DFL关闭;
6.接收端会对信号做的反应
(1)默认处理
(2)忽略(9、19)不能被忽略
(3)自定义处理、捕获(9、19)不能被修改