1. 管道:简单
实现原理: 操作系统的内核借助环形队列机制,使用内核缓冲区实现。
特质: 1. 伪文件
2. 管道中的数据只能一次读取。
3. 数据在管道中,只能单向流动。
局限性:1. 自己写,不能自己读。
2. 数据不可以反复读。
3. 半双工通信。
4. 血缘关系进程间可用。
pipe函数: 创建,并打开管道。
函数用法:
int pipe(int fd[2]);
参数:fd[0]: 读端
fd[1]: 写端。
一个管道通信的示例,父进程往管道里写,子进程从管道读,然后打印读取的内容:
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. #include <unistd.h>
5. #include <errno.h>
6. #include <pthread.h>
7.
8. void sys_err(const char *str)
9. {
10. perror(str);
11. exit(1);
12. }
13.
14. int main(int argc, char *argv[])
15. {
16. int ret;
17. int fd[2];
18. pid_t pid;
19.
20. char *str = "hello pipe\n";
21. char buf[1024];
22.
23. ret = pipe(fd);
24. if (ret == -1)
25. sys_err("pipe error");
26.
27. pid = fork();
28. if (pid > 0) {
29. close(fd[0]); // 关闭读段
30. //sleep(3);
31. write(fd[1], str, strlen(str));
32. close(fd[1]);
33. } else if (pid == 0) {
34. close(fd[1]); // 子进程关闭写段
35. ret = read(fd[0], buf, sizeof(buf));
36. printf("child read ret = %d\n", ret);
37. write(STDOUT_FILENO, buf, ret);
38.
39. close(fd[0]);
40. }
41.
42. return 0;
43. }
2. 命名管道FIFO
管道的优劣:
优点:1. 相比信号、套接字实现进程通信要简单很多
2. 可用于无血缘关系的进程间通信
缺点:1.只能单向通信,双向通信需建立两个管道
2.只能用于有血缘关系的进程间通信。该问题后来使用fifo命名管道解决。
命名管道函数:mkfifo
读端,open fifo O_RDONLY
写端,open fifo O_WRONLY
一个写fifo,一个读fifo,操作起来就像文件一样
2. 信号:开销小
-
信号是软件层面上的“中断”。一旦信号产生,无论程序执行到什么位置,必须立即停止运行,处理信号。
-
所有信号的产生及处理全部都是由【内核】完成的。
产生信号: 1. 按键产生:Ctrl+c、Ctrl+z 2. 系统调用产生:kill 3. 软件条件产生: alarm函数——设置定时器,发送14)SIGALARM信号 settime函数 4. 硬件异常产生:除0操作、非法访问内存(段错误) 5. 命令产生:kill命令 signal实现指定的信号捕捉,并设置相关的操作函数handler
概念:
未决信号:产生与递达之间状态。 递达信号:产生并且送达到进程。直接被内核处理掉。 信号处理方式: 执行默认处理动作、忽略、捕捉(自定义) 本质是位图的两个信号集 阻塞信号集(信号屏蔽字): 记录信号的屏蔽状态。 一旦被屏蔽的信号,在解除屏蔽前,一直处于未决态。 未决信号集:记录信号的处理状态。 该信号集中的信号,表示已经产生,但尚未被处理。
3. mmap映射:非血缘关系进程间
存储映射I/O(Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相映射。
从缓冲区中取数据,就相当于读文件中的相应字节。
与此类似,将数据存入缓冲区,则相应的字节就自动写入文件。
这样就可在不使用read、write函数的情况下,使地址指针完成I/O操作。
减少用户空间到内核空间的传输成本。
使用方法:首先通知内核,将一个指定文件映射到存储区域中。
这个映射工作可以通过mmap函数来实现。
mmap函数:
创建共享内存映射
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
参数:
addr:指定映射区的首地址。通常传NULL,表示让系统自动分配
length:共享内存映射区的大小。(<= 文件的实际大小)
prot:共享内存映射区的读写属性。PROT_READ、PROT_WRITE、PROT_READ|PROT_WRITE
flags:标注共享内存的共享属性。MAP_SHARED(修改会反映到磁盘上)、MAP_PRIVATE(修改不反映到磁盘上)
fd:用于创建共享内存映射区的那个文件的 文件描述符。
offset:默认0,表示映射文件全部。偏移位置。需是 4k 的整数倍。
释放映射区。
int munmap(void *addr, size_t length);
addr是mmap函数的返回值