概述
目录
- 前言
- 1、匿名管道(PIPE)
- 2、命名管道(FIFO)
- 3、信号
- 4、共享内存映射
- 5、共享内存
- 6、消息队列
- 7、信号量
- 8、UNIX域套接字(Unix Domain Socket)
- socketpair
前言
Linux环境下,进程地址空间相互独立、彼此隔离,因此进程间的数据不能之间访问。如果要交换数据,必须要通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷贝到内核缓冲区,进程B再把数据从内核缓冲区拷贝走,内核提供的这种机制称为进程间通信(IPC, InterProcess Communication)
在Linux下由很多种进程间通信的方式,在下面主要介绍八种,分别是:匿名管道(PIPE)、命名管道(FIFO)、信号、共享内存映射、共享内存、消息队列、信号量、UNIX域套接字。现在常用的进程间通信方式有:
- 管道(使用简单)
- 信号(开销最小)
- 共享内存(效率最高)
- UNIX域套接字(最稳定)
1、匿名管道(PIPE)
管道是一种最基本的IPC,用于有血缘关系的进程之间。使用的系统调用如下:
int pipe(int pipefd[2]);
管道有如下特征:
- 本质是一个伪文件(实为内核缓冲区)
- 由两个文件描述符引用,一个表示写端,一个表示读端
- 数据从管道的写端流入,从读端流出
- 采用半双工通信方式,数据只能从一个方向上流动。如果需要全双工,可以创建两个管道。
**管道的原理:**管道实为内核使用环形队列机制,借助内核缓冲区实现(大小4K)
父子进程通过管道通信:
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int fds[2];
pid_t pid;
int ret;
char buf[1024];
if (pipe(fds) < 0) {
perror("open pipe error:");
exit(1);
}
pid = fork();
if (pid < 0) {
perror("fork error:");
exit(2);
} else if (pid > 0) { // parend process
// parent process write to pipe
close(fds[0]); // close read end
ret = write(fds[1], "I am your father", strlen("I am your father"));
if (ret < 0) {
perror("parent write pipe error:");
exit(3);
}
printf("parent process id:%u, son:%u, write successn", getpid(), pid);
wait(NULL);
} else { // child process
// child process read from pipe
close(fds[1]); // close wirte end
ret = read(fds[0], buf, sizeof(buf));
if (ret < 0) {
perror("child read pipe error:");
exit(3);
}
buf[ret] = '