В некоторых системах трубы могут быть двунаправленными. Но они не должны быть, и любое предположение, что они будут, непереносимо. В частности, они не работают в Linux.
В действительности ваш код имеет проблему - оба процесса пытаются читать и записывать в один и тот же канал. Предполагаемое использование для каналов - то, что ребенок пишет, а родитель читает, или наоборот. Текущий способ, которым вы все делаете, работает для вас прямо сейчас, потому что вы читаете и пишете один раз и wait
обращаетесь к ребенку. Но когда вы зацикливаетесь, пытаясь сделать то же самое, что и вы, вы не можете wait
- и без синхронизации ребенок часто (но не всегда!) В конечном итоге читает то, что он намеревался отправить родителю. и наоборот.
Если вы хотите, чтобы данные передавались в обоих направлениях, вы можете использовать две пары каналов. Давайте назовем их parent_pipe
и child_pipe
. Родитель будет читать из parent_pipe[0]
и писать в child_pipe[1]
, а ребенок будет читать из 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);
}
}
}
В качестве альтернативы, вы можете использовать пару сокетов UNIX, созданных с помощью socketpair(AF_LOCAL, SOCK_STREAM, 0, sockdes)
(где sockdes
- это то, к чему мы переименовали pipdes
, поскольку теперь это сокеты, а не каналы). Ребенок читает и пишет в sockdes[0]
, а родитель читает и пишет в sockdes[1]
. Или наоборот.