Что вызывает зависание моей программы и ее неправильное завершение? (труба, чтение системного вызова, пока цикл)
У меня есть программа, в которой я пишу из нескольких дочерних процессов в канал, а затем пытаюсь прочитать все сообщения, записанные каждому процессу, из каждого канала и распечатать их на экране. С помощью следующего кода (в частности, цикла while, использующего read
системный вызов для хранения сообщений в буфере buf
), моя программа будет зависать, не будет выходить и не печатать все сообщения, отправленные различным процессам.
for (i = 0; i < MAXP; i++) {
if(id == i) {
while(read(pfds[i][0], buf, sizeof(buf)) > 0)
printf("process%d has received a message from %s\n",i,buf);
}
}
Однако с помощью следующего кода программа завершает работу корректно, но не печатает все сообщения (так как они не все прочитаны):
for (i = 0; i < MAXP; i++) {
if(id == i) {
nbytes = read(pfds[i][0], buf, sizeof(buf));
printf("process%d has received a message from %s\n",i,buf);
}
}
Это мой код записи в каналы:
write(pfds[j][1],msg,9); // write the message to j pipe
и сообщение:
sprintf(msg, "process%d", i); // create the message - 9 bytes (inc. null term)
// the message is "process0" or "process1" ... through "process8"
который является 9-байтовым массивом символов:
char msg[9];
Решение
for (j = 0; j < MAXP; j++) {
close(pfds[j][1]); // close write to j from i
}
2 ответа
Может б / к ты не закрыл трубу? если конец записи не закрыт, чтение продолжит зависать
Попытка добавления
close(pfds[j][1]);
после того, как вы напишите свои сообщения в трубу
read(fd)
(где fd
конец чтения канала) вернет только 0
когда все концы записи для канала были закрыты.
Обратите внимание, что fork()
-ing будет дублировать все дескрипторы открытых файлов. Итак, это:
int fd[2];
pipe(fd);
if (fork() == 0) {
write(fd[1], "abc", 3);
close(fd[1]);
} else {
char buf[100];
while (read(fd[0], buf, 100) > 0) {
// ...
}
}
вызовет бесконечный цикл (потому что fd[1]
все еще открыт в родительском процессе), пока это:
int fd[2];
pipe(fd);
if (fork() == 0) {
write(fd[1], "abc", 3);
close(fd[1]);
} else {
close(fd[1]);
char buf[100];
while (read(fd[0], buf, 100) > 0) {
// ...
}
}
должен прекратить.