【项目 进程6】 2.13 匿名管道通信案例 2.14管道的读写特点和管道设置为非阻塞
发布人:shili8
发布时间:2025-02-15 11:28
阅读次数:0
**项目进程6**
###2.13 匿名管道通信案例在前面的章节中,我们已经学习了如何使用匿名管道进行进程间通信。现在,让我们来看一个具体的案例。
#### 案例描述有两个进程,分别是父进程和子进程。父进程需要向子进程传递一些数据,而子进程需要从父进程中读取这些数据。为了实现这一点,我们可以使用匿名管道进行通信。
####代码示例
c#include <stdio.h> #include <stdlib.h> #include <unistd.h> // 父进程函数void parent_func() { int pipefd[2]; // 匿名管道描述符数组 char buffer[1024]; // 创建匿名管道 if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } // 父进程向子进程写入数据 write(pipefd[1], "Hello, child!",13); // 子进程从父进程读取数据 read(pipefd[0], buffer,1024); printf("Parent: %s ", buffer); } // 子进程函数void child_func() { int pipefd[2]; // 匿名管道描述符数组 // 创建匿名管道 if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } char buffer[1024]; // 子进程从父进程读取数据 read(pipefd[0], buffer,1024); printf("Child: %s ", buffer); // 关闭匿名管道 close(pipefd[0]); close(pipefd[1]); } int main() { pid_t pid; // 创建子进程 if ((pid = fork()) == -1) { perror("fork"); exit(EXIT_FAILURE); } if (pid ==0) { // 子进程 child_func(); } else { // 父进程 parent_func(); } return0; }
在这个案例中,我们创建了一个匿名管道,并使用 `write` 和 `read` 函数进行通信。父进程向子进程写入数据,而子进程从父进程读取数据。
###2.14 管道的读写特点和管道设置为非阻塞####1. 管道的读写特点在前面的章节中,我们已经学习了如何使用匿名管道进行进程间通信。现在,让我们来看一下管道的读写特点。
* **读端**:当读端没有数据可读时,`read` 函数会阻塞直到有数据可读。
* **写端**:当写端没有空间可写时,`write` 函数会阻塞直到有空间可写。
####2. 管道设置为非阻塞在某些情况下,我们可能需要避免管道的阻塞。例如,如果我们正在处理大量数据,并且不希望读取或写入数据时阻塞进程,那么就可以使用非阻塞模式。
要设置管道为非阻塞模式,可以使用 `fcntl` 函数,具体来说,可以使用以下命令:
cint fd = open("pipe", O_RDWR); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } struct flock fl; fl.l_type = F_WRLCK; //读写锁fl.l_whence = SEEK_SET; // 从开头开始fl.l_start =0; // 开始位置为0fl.l_len =0; // 长度为0if (fcntl(fd, F_SETLK, &fl) == -1) { perror("fcntl"); exit(EXIT_FAILURE); }
在这个例子中,我们使用 `open` 函数打开管道,并使用 `fcntl` 函数设置读写锁。这样可以避免管道的阻塞。
####3. 使用非阻塞模式的示例现在,让我们看一个使用非阻塞模式的示例:
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]; while (1) { ssize_t bytes_read = read(pipefd[0], buffer,1024); if (bytes_read >0) { printf("%s ", buffer); } else if (bytes_read == -1) { perror("read"); exit(EXIT_FAILURE); } // 使用非阻塞模式 struct flock fl; fl.l_type = F_WRLCK; //读写锁 fl.l_whence = SEEK_SET; // 从开头开始 fl.l_start =0; // 开始位置为0 fl.l_len =0; // 长度为0 if (fcntl(pipefd[1], F_SETLK, &fl) == -1) { perror("fcntl"); exit(EXIT_FAILURE); } write(pipefd[1], "Hello, world!",13); close(pipefd[0]); close(pipefd[1]); return0; } }
在这个例子中,我们使用非阻塞模式读取管道中的数据,并写入新的数据。