gpt4 book ai didi

c - UNIX 中的管道不应该是单向的吗?

转载 作者:太空狗 更新时间:2023-10-29 17:04:42 26 4
gpt4 key购买 nike

看看下面的代码:

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>

main() {
int pipdes[2];
char buff[50];
const char parent[]="Parent Writes. Child Reads\n";
const char child[]="Child Writes. Parent Reads\n";
if(pipe(pipdes)==0) {
pid_t pid=fork();
if(pid<0)
printf("Error\n");
if(pid==0){
read(pipdes[0],buff,50);
printf("Parent: %s",buff);
write(pipdes[1], child, strlen(child));
exit(0);
}
else if(pid>0) {
write(pipdes[1], parent, strlen(parent));
wait(pid);
read(pipdes[0], buff, 50);
printf("Child: %s", buff);
}
}
else
printf("Error in pipe\n");
}

现在,我在这里只创建了一个管道,但两个进程都可以从中读取和写入。管道不应该是单向的。此外,当我为父项放置常规的“close(pipdes[0])”,为子项放置“close(pipdes[1])”时,代码不起作用,尽管我添加了 open(pipdes[0]) 函数稍后。

我对 UNIX 和管道的概念仍然很原始,所以我在这里可能有点蹩脚,但请提供帮助。

最佳答案

在某些系统上,管道可以是双向的。但它们不一定是,而且任何关于它们将是的假设都是不可移植的。特别是,它们不在 Linux 上。

实际上,您的代码有问题——两个进程都试图从同一个管道读取和写入。管道的预期用途是子级写入而父级读取,反之亦然。您当前做事的方式现在适合您,因为您只读和写一次并且等待 child 。但是,当您尝试按照您正在做的方式做事时循环播放时,您不能等待——如果没有同步, child 通常(但不总是!)最终会读到它想要的内容发送给 parent ,反之亦然。

如果您希望数据双向流动,您可以使用两对管道。我们称它们为 parent_pipechild_pipe。 parent 将从 parent_pipe[0] 读取并写入 child_pipe[1], child 将从 child_pipe[0] 读取并写入到 parent_pipe[1]

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>

int main() {
int parent_pipe[2];
int child_pipe[2];
char buff[50];

if(pipe(parent_pipe) || pipe(child_pipe)) {
perror("pipe(...)");
exit(1);
}

// As noted elsewhere, you're using `fork()` incorrectly.
// `fork()` returns 0 to the child, and a pid to the parent, or -1 if an error
// occurs.
int pid = fork();
if (pid == -1) {
perror("fork()");
exit(1);
}

if (pid == 0) {
// this is the child process. read from child_pipe, write to parent_pipe
const char child[]="Child Writes. Parent Reads\n";
int in, out;
in = child_pipe[0];
// in = parent_pipe[0]; // uncomment me to test with one pipe pair
out = parent_pipe[1];

for (int i = 0; i < 10; ++i) {
read(in,buff,50);
printf("Parent: %s",buff);
// NOTE: `strlen(child)` doesn't include the nul at the end!
write(out, child, strlen(child) + 1);
}
}
else {
// this is the parent process
const char parent[]="Parent Writes. Child Reads\n";
int in, out;
in = parent_pipe[0];
out = child_pipe[1];
// out = parent_pipe[1]; // uncomment me to test with one pipe pair

for (int i = 0; i < 10; ++i) {
write(out, parent, strlen(parent) + 1);
read(in, buff, 50);
printf("Child: %s", buff);
}
}
}

或者,您可以使用一对通过 socketpair(AF_LOCAL, SOCK_STREAM, 0, sockdes) 创建的 UNIX 套接字(其中 sockdes 是我们重命名为 pipdes 到,因为它现在是套接字而不是管道)。 child 会读取和写入sockdes[0],而 parent 会读取和写入sockdes[1]。反之亦然。

关于c - UNIX 中的管道不应该是单向的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8390799/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com