【项目 进程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;
}
}
在这个例子中,我们使用非阻塞模式读取管道中的数据,并写入新的数据。

