Хорошо, во-первых, вы не получаете всего случайного запутанного слова HELLO и WORLD, потому что stdout буферизован.
Итак, ваш родитель печатает ПРИВЕТ, пока этот буфер не заполнится, а затем весь этот буфер не окажется на вашем экране. То же самое для ребенка.
Если вы хотите синхронизировать это, вы можете использовать 2 канала для связи между вашим родителем и ребенком.
например
- родительские принты "HELLO",
- ребенок начинает читать с трубы1.
- parent пишет символ в pipe1, чтобы сигнализировать, что потомок должен вывести «WORLD»
- родитель начинает чтение с канала2
- ребенок читает из pipe1, печатает "МИР"
- child пишет символ в pipe2, чтобы указать, что родитель должен напечатать «HELLO»
- повторите вышеупомянутое
-
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void err(const char *error)
{
perror(error);
exit(1);
}
void run_handler(int readfd,int writefd,const char *message)
{
for(;;) {
char ch;
int i;
if((i = read(readfd,&ch,1)) == 0)
break;
else if(i < 0)
err("read");
//important: fflush the text so it ends up in the output
//and not in an internal FILE* buffer.
if(fputs(message,stdout) == EOF || fflush(stdout) == EOF)
break;
if(write(writefd,&ch,1) != 1)
err("write");
}
}
int main()
{
int pipe1[2];
int pipe2[2];
pid_t pid;
if(pipe(pipe1) != 0)
err("pipe1");
if(pipe(pipe2) != 0)
err("pipe2");
if((pid = fork()) == 0 ) {
//write one char to the parent to get it started
char ch = '.';
if(write(pipe1[1],&ch,1) != 1)
err("write");
//close the pipe ends we don't need
close(pipe1[0]);
close(pipe2[1]);
run_handler(pipe2[0],pipe1[1],"WORLD\n");
}else if(pid > 0) {
//close the pipe ends we don't need
close(pipe1[1]);
close(pipe2[0]);
run_handler(pipe1[0],pipe2[1],"HELLO ");
} else {
err("fork");
}
return 0;
}