嵌入式Linux学习 -- 进程和线程4
四、进程间通信
1. 概念
- 进程空间是独立的,包含文本段、数据段和系统数据段
- 多个进程没有共享的用户空间,进程是操作系统资源分配的最小单元
- 可以利用Linux内核实现多个进程间的通信
2. 通信方式
1. 传统Unix系统中的通信方式
管道,信号
2. SYS V分支中的通信方式
消息队列,共享内存,信号灯
3. BSD分支中的通信方式
本地域套接字
3. 管道
1. 分类
无名管道 -- 只能用于具有亲缘关系的进程间通信
有名管道
2. 无名管道
1. 原理
- 无名管道是一段内核缓存区
- 父进程通过pipe创建无名管道
- 只有该父进程的子进程才能继承得到这两个文件描述符,才能实现通信
- 只能用于具有亲缘关系的进程间通信
2. 函数接口
pipe
- 原型:int pipe(int pipefd[2]);
- 功能:
创建一个无名管道(内核缓存区)
- 参数:
pipefd[0]:读管道文件描述符
pipefd[1]:写管道文件描述符
- 返回值:
成功返回0,失败返回-1
3. 特性
1. 管道中至少有一个写端:
读取数据时,如果管道中有数据则直接读出
读取数据时,如果管道中没有数据则阻塞等待有数据写入才能读出
2. 管道中没有写端:
读取数据时,管道中有数据则直接读出
读取数据时,管道中没有数据不阻塞等待直接向下执行
3. 管道中至少有一个读端:
写入数据时,如果管道没有写满则直接写入
写入数据时,如果管道存满则阻塞等待有数据读出才能继续写入
4. 管道中没有读端
写入数据时,会产生管道破裂的信号导致进程任务异常退出
3. 有名管道
1. 无名管道 与 有名管道
- 有名管道有名字,可以通过名字找到该管道
- 可以用于任意进程间的通信
- 进程间通信最简单、易实现的方式
- 有名管道必须读写两端同时加入才能继续向下执行
2. 操作方式
进程一、二使用open以只读、只写或读写方式打开管道文件
两个进程可以通过向管道文件中读写数据实现进程的通信
3. 函数接口
mkfifo
- 原型:int mkfifo(const char *pathname, mode_t mode);
- 功能:
创建有名管道
- 参数:
pathname:管道文件名
mode:权限
- 返回值:
成功返回0,失败返回-1
通过进程间通信实现读写端口彼此循环接收和发送信息
read.c:
write.c:
结果:
4. 多任务实现进程间通信
A:
B:
Makefile:
结果:
4. 信号
1. 概念
- Linux系统中的信号主要实现应用层和内核层之间的信号通知
- 应用层与内核层之间通信的信号根据含义分为很多不同的信号
- 信号主要用于多个进程任务间的事件通知
- 信号可以用户异步通信
2. 类型
通过 kill -l查看信号类型
2) SIGINT:中止信号(可以从键盘输入) ctrl + c
3) SIGQUIT:退出信号(可以从键盘输入) ctrl + \
9) SIGKILL:杀死进程信号
11)SIGSEGV:段错误信号
13)SIGPIPE:管道破裂信号
14)SIGALARM:定时时间到达信号
17)SIGCHLD:子进程结束时,父进程回收到该信号
18)SIGCONT:继续执行进程任务
19)SIGSTOP:停止进程任务
20)SIGTSTP:挂起信号(可以从键盘输入) ctrl + z
29)SIGIO:异步IO信号
3. 处理方式
1. 缺省
信号来了,按照默认方式处理
2. 忽略
信号来了,不处理信号,忽略信号
3. 捕捉
信号来了,按照用户自己定义的方式处理信号
9号信号(SIGKILL)和19号信号(SIGSTOP)不能被忽略和捕捉的
4. 函数接口
1. signal
- 原型:
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- 功能:
设置signum对应信号的处理方式
- 参数:
signum:信号的编号
handler:信号的处理方式
SIG_IGN:忽略信号
SIG_DFL:缺省处理信号
- 返回值:
成功返回之前处理信号的方式
失败返回SIG_ERR
此时使用 kill 退出程序
2. alarm
- 原型:unsigned int alarm(unsigned int seconds);
- 功能:
设置第一个定时,过seconds秒后,给进程发送SIGALRM信号
- 参数:
seconds:秒数
- 返回值:
成功返回上次定时剩余的秒数,如果之前没有定时返回0
通过 alarm 函数实现时间循环打印
3. kill
- 原型:int kill(pid_t pid, int sig);
- 功能:
给pid对应的进程发送sig信号
- 参数:
pid:进程的ID号
sig:信号的编号
- 返回值:
成功返回0,失败返回-1