Поэтому я пытаюсь настроить связь между родителем (компьютерная система) и его дочерним (системная шина), а также между дочерним (системная шина) и внуком (устройство ввода-вывода). Я не пытаюсь установить связь между родителем и внуком. Мой код работал нормально, когда он был только родителем и потомком, однако, когда я добавил в каналы для child-> grandchild and grandchild-> child, он не работает; в частности, внук не может общаться с ребенком.
Я поместил «<---- ОШИБКА», где код, который я добавляю, останавливает программу и завершает работу. Без этих строк программа работает, но общаются только родитель и ребенок. Я делаю это неправильно? Или есть тонкая ошибка, которую я пропускаю? </p>
Я извиняюсь, потому что я довольно плохо знаком с этим материалом трубопровода, и благодарен за любую оказанную помощь. Я буду продолжать пытаться найти проблему сегодня вечером, и, надеюсь, один из вас сможет помочь завтра.
Вот мой код:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void computer_system (int pipe_cpu_bus[], int pipe_bus_cpu[], int length);
void system_bus (int pipe_cpu_bus[], int pipe_bus_cpu[], char *filename);
void io_device (int pipe_bus_io[], int pipe_io_bus[], char *filename);
void transfer_device (int pipe_bus_tran[]);
void buffer (int pipe_bus_buf[]);
#define MSGSIZE 20
int
main (int argc, char **argv) {
// a pipe from cpu to bus,
// use 1 within cpu to write to bus
// use 0 within bus to read from cpu
int pipe_cpu_bus[2];
// a pipe from bus to cpu,
// use 1 within bus to write to cpu
// use 0 within cpu to read from bus
int pipe_bus_cpu[2];
// error checking for pipe
if (pipe(pipe_cpu_bus) < 0)
exit(1);
if (pipe(pipe_bus_cpu) < 0)
exit(1);
// error checking for fcntl
if (fcntl(pipe_cpu_bus[0], F_SETFL, O_NONBLOCK) < 0)
exit(2);
if (fcntl(pipe_bus_cpu[0], F_SETFL, O_NONBLOCK) < 0)
exit(2);
switch (fork()) {
// error
case -1:
exit(3);
// child process (COMPUTER SYSTEM)
case 0:
if (argc >= 3) {
int length = atoi(argv[2]);
computer_system(pipe_cpu_bus, pipe_bus_cpu, length);
}
else {
printf("Usage: %s <file_name> <number>", argv[0]);
}
break;
// parent process (SYSTEM BUS)
default:
if (argc >= 3) {
char* filename = argv[1];
system_bus(pipe_cpu_bus, pipe_bus_cpu, filename);
}
else {
printf("Usage: %s <file_name> <number>", argv[0]);
}
break;
}
return 0;
}
void
computer_system (int pipe_cpu_bus[], int pipe_bus_cpu[], int length) {
int nread;
char buf[MSGSIZE];
close(pipe_cpu_bus[0]); // close read end of cpu_bus
close(pipe_bus_cpu[1]); // close write end of bus_cpu
write(pipe_cpu_bus[1], "hello", 5);
while (1) {
memset(buf, 0, sizeof buf);
nread = read(pipe_bus_cpu[0], buf, MSGSIZE);
switch (nread) {
// case -1 means pipe is empty and errono set EAGAIN
case -1:
if (errno == EAGAIN) {
printf(" (pipe empty in cpu)\n");
sleep(1);
break;
}
else {
perror("read");
exit(4);
}
// case 0 means all bytes are read and EOF (end of conv.)
case 0:
close(pipe_bus_cpu[0]);
close(pipe_cpu_bus[1]);
exit(0);
// some bytes have been read
default:
printf("bus: %s\n", buf);
write(pipe_cpu_bus[1], "hello", 5);
sleep(1);
}
}
exit(0);
}
void
system_bus (int pipe_cpu_bus[], int pipe_bus_cpu[], char *filename) {
// ======== CREATE IO PROCESS ========
int pipe_io_bus[2], pipe_bus_io[2];
// error checking for pipe
if (pipe(pipe_io_bus) < 0)
exit(1);
if (pipe(pipe_bus_io) < 0)
exit(1);
// error checking for fcntl
if (fcntl(pipe_io_bus[0], F_SETFL, O_NONBLOCK) < 0)
exit(2);
if (fcntl(pipe_bus_io[0], F_SETFL, O_NONBLOCK) < 0)
exit(2);
switch (fork()) {
// error
case -1:
exit(3);
// child process (COMPUTER SYSTEM)
case 0:
io_device(pipe_io_bus, pipe_bus_io, filename);
break;
default:
break;
}
// ===================================
int nread;
char buf[MSGSIZE];
close(pipe_cpu_bus[1]); // close write end of cpu_bus
close(pipe_bus_cpu[0]); // close read end of bus_cpu
close(pipe_io_bus[1]); // <--- ERROR
close(pipe_bus_io[0]); // <--- ERROR
while (1) {
// ==== Read from IO ====
memset(buf, 0, sizeof buf);
nread = read(pipe_io_bus[0], buf, MSGSIZE);
switch (nread) {
// case -1 means pipe is empty and errono set EAGAIN
case -1:
if (errno == EAGAIN) {
printf(" (io pipe empty in bus)\n");
sleep(1);
break;
}
else {
perror("read");
exit(4);
}
// case 0 means all bytes are read and EOF (end of conv.)
case 0:
close(pipe_io_bus[0]);
close(pipe_bus_io[1]);
exit(0);
// some bytes have been read
default:
printf("io: %s\n", buf);
write(pipe_bus_io[1], "fuck off", 8);
sleep(1);
}
// ==== Read from CPU ====
memset(buf, 0, sizeof buf);
nread = read(pipe_cpu_bus[0], buf, MSGSIZE);
switch (nread) {
// case -1 means pipe is empty and errono set EAGAIN
case -1:
if (errno == EAGAIN) {
printf(" (cpu pipe empty in bus)\n");
sleep(1);
break;
}
else {
perror("read");
exit(4);
}
// case 0 means all bytes are read and EOF (end of conv.)
case 0:
close(pipe_cpu_bus[0]);
close(pipe_bus_cpu[1]);
exit(0);
// some bytes have been read
default:
printf("cpu: %s\n", buf);
write(pipe_bus_cpu[1], "fuck off", 8);
sleep(1);
}
}
}
void
io_device (int pipe_bus_io[], int pipe_io_bus[], char *filename) {
int nread;
char buf[MSGSIZE];
close(pipe_io_bus[0]); // close read end of bus_io
close(pipe_bus_io[1]); // close write end of io_bus
write(pipe_io_bus[1], "here is a message", 17);
while (1) {
memset(buf, 0, sizeof buf);
nread = read(pipe_bus_io[0], buf, MSGSIZE);
switch (nread) {
// case -1 means pipe is empty and errono set EAGAIN
case -1:
if (errno == EAGAIN) {
printf(" (pipe empty in io)\n");
sleep(1);
break;
}
else {
perror("read");
exit(4);
}
// case 0 means all bytes are read and EOF (end of conv.)
case 0:
close(pipe_bus_io[0]);
close(pipe_io_bus[1]);
exit(0);
// some bytes have been read
default:
printf("bus: %s\n", buf);
write(pipe_io_bus[1], "here is a message", 17);
sleep(1);
}
}
}
Как вы можете видеть, без этих двух строк, которые вызывают Программа для выхода по неизвестной причине работает, но шина (дочерняя) ничего не получает от io (внука), несмотря на то, что io явно пишет в нее.
Если две строки не пропущены, печать отладки выглядит следующим образом:
(pipe empty in cpu)
(io pipe empty in bus)
(pipe empty in cpu)
cpu: hello
bus: fuck off
Вот выходные данные отладки, если вам это требуется.
(pipe empty in cpu)
(io pipe empty in bus)
(pipe empty in io)
(pipe empty in cpu)
(pipe empty in io)
cpu: hello
bus: fuck off
(pipe empty in io)
(io pipe empty in bus)
(pipe empty in cpu)
(pipe empty in io)
cpu: hello
bus: fuck off
(io pipe empty in bus)
(pipe empty in io)
(pipe empty in cpu)
cpu: hello
(pipe empty in io)
^C⏎