【Linux】进程间通信——管道/共享内存
发布人:shili8
发布时间:2025-01-30 00:06
阅读次数:0
**Linux 进程间通信**
在 Linux 中,进程间通信(Inter-Process Communication, IPC)是指不同进程之间的数据交换和同步。IPC 是一个重要的概念,因为它使得多个进程能够协同工作,实现复杂的任务。
本文将介绍两种常见的 IPC 方式:管道(Pipe)和共享内存(Shared Memory)。我们将通过代码示例和注释来深入理解这些概念。
**1. 管道**
管道是一种简单的 IPC 方式,它允许两个进程之间进行数据传输。管道由一个缓冲区组成,进程可以向该缓冲区写入数据,而另一个进程可以从该缓冲区读取数据。
###1.1 管道创建要使用管道,我们需要使用 `pipe()` 系统调用来创建一个管道:
c#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { int pipefd[2]; // 管道描述符数组 if (pipe(pipefd) == -1) { // 创建管道 perror("pipe"); exit(EXIT_FAILURE); } return0; }
在上面的代码中,我们使用 `pipe()` 系统调用创建了一个管道,得到的两个描述符分别是 `pipefd[0]` 和 `pipefd[1]`。`pipefd[0]` 是用于读取数据的描述符,而 `pipefd[1]` 是用于写入数据的描述符。
###1.2 管道写入和读取要向管道中写入数据,我们使用 `write()` 系统调用:
c#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { int pipefd[2]; if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } char buffer[] = "Hello, world!"; write(pipefd[1], buffer, strlen(buffer)); // 向管道写入数据 return0; }
在上面的代码中,我们使用 `write()` 系统调用向管道中写入了一个字符串。
要从管道中读取数据,我们使用 `read()` 系统调用:
c#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { int pipefd[2]; if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } char buffer[1024]; read(pipefd[0], buffer,1024); // 从管道读取数据 printf("%s ", buffer); return0; }
在上面的代码中,我们使用 `read()` 系统调用从管道中读取了一个字符串,并将其打印到标准输出。
**2. 共享内存**
共享内存是一种 IPC 方式,它允许多个进程共享同一块内存区域。共享内存是通过 `shmget()` 和 `shmat()` 系统调用来实现的。
###2.1 共享内存创建要使用共享内存,我们需要使用 `shmget()` 系统调用来创建一个共享内存区域:
c#include <stdio.h> #include <stdlib.h> #include <sys/shm.h> int main() { int shm_id = shmget(IPC_PRIVATE,1024, IPC_CREAT |0644); // 创建共享内存区域 if (shm_id == -1) { perror("shmget"); exit(EXIT_FAILURE); } return0; }
在上面的代码中,我们使用 `shmget()` 系统调用创建了一个共享内存区域,得到的 ID 是 `shm_id`。
###2.2 共享内存映射要将共享内存区域映射到进程的虚拟地址空间中,我们使用 `shmat()` 系统调用:
c#include <stdio.h> #include <stdlib.h> #include <sys/shm.h> int main() { int shm_id = shmget(IPC_PRIVATE,1024, IPC_CREAT |0644); if (shm_id == -1) { perror("shmget"); exit(EXIT_FAILURE); } char *shm_ptr = shmat(shm_id, NULL,0); // 将共享内存区域映射到进程的虚拟地址空间中 return0; }
在上面的代码中,我们使用 `shmat()` 系统调用将共享内存区域映射到了进程的虚拟地址空间中,得到的指针是 `shm_ptr`。
###2.3 共享内存写入和读取要向共享内存区域中写入数据,我们使用 `write()` 系统调用:
c#include <stdio.h> #include <stdlib.h> #include <sys/shm.h> int main() { int shm_id = shmget(IPC_PRIVATE,1024, IPC_CREAT |0644); if (shm_id == -1) { perror("shmget"); exit(EXIT_FAILURE); } char buffer[] = "Hello, world!"; write(shm_id, buffer, strlen(buffer)); // 向共享内存区域中写入数据 return0; }
在上面的代码中,我们使用 `write()` 系统调用向共享内存区域中写入了一个字符串。
要从共享内存区域中读取数据,我们使用 `read()` 系统调用:
c#include <stdio.h> #include <stdlib.h> #include <sys/shm.h> int main() { int shm_id = shmget(IPC_PRIVATE,1024, IPC_CREAT |0644); if (shm_id == -1) { perror("shmget"); exit(EXIT_FAILURE); } char buffer[1024]; read(shm_id, buffer,1024); // 从共享内存区域中读取数据 printf("%s ", buffer); return0; }
在上面的代码中,我们使用 `read()` 系统调用从共享内存区域中读取了一个字符串,并将其打印到标准输出。
**总结**
本文介绍了两种常见的 IPC 方式:管道和共享内存。我们通过代码示例和注释来深入理解这些概念。管道是一种简单的 IPC 方式,它允许两个进程之间进行数据传输,而共享内存是一种更复杂的 IPC 方式,它允许多个进程共享同一块内存区域。
希望本文对您有所帮助。如果您有任何问题或疑问,请随时与我联系。