Я пишу программу, состоящую из 2 процессов. Родитель читает данные через stdin, а затем отправляет их дочернему устройству через канал. Я использую функции fgets() и fputs() для записи и чтения данных.Сложность с использованием fgets при чтении строк по трубе
Проблема в том, что в определенных ситуациях вызов функции fgets() дочернего процесса блокируется. Это:
- Когда текстовый файл отправляется на stdin, все работает нормально до самой последней строки файла. Fgets ребенка никогда не выполняется и процесс зависает.
- Когда я отправляю/dev/urandom к программе, такая же ситуация происходит в случайный момент.
Я подозреваю, что проблема имеет какое-то отношение к EOF или/0 в конце этих строк, но я не могу точно определить проблему. Любая помощь будет принята с благодарностью.
Я использую очереди сообщений как средство синхронизации. Я также знаю, что в этом коде нет очистки. Вот оно:
#define KEY5 7626
struct pidbuf
{
long mtype;
int mtext;
} msgpid;
int main(){
sleep(5);
int mqpid;
FILE * strumien;
int fd[2];
if (pipe(fd)== -1){
perror("Create pipe error");
exit(1);}
int buf_len = 128;
msgpid.mtext=0;
int size1=sizeof(struct pidbuf)-sizeof(long);
if((mqpid = msgget(KEY5, 0666 | IPC_CREAT))==-1){
return(-1);
}
char data[buf_len];
if(fork()!=0){
close(fd[0]);
strumien=fdopen(fd[1],"w");
while (fgets(data,buf_len,stdin) != NULL) {
printf("1:\n%s\n",data);
fputs(data,strumien);
fflush(strumien);
msgpid.mtype=2;
if(msgsnd(mqpid,&msgpid,size1,0)==-1){perror("msgsnd failed: 1");}
msgrcv(mqpid,&msgpid,size1, 1, 0);
}
if(feof(stdin)!=0) printf("\nEnd of file\n");
}
else{
close(fd[1]);
strumien=fdopen(fd[0],"r");
msgrcv(mqpid,&msgpid,size1, 2, 0);
while(fgets(data,buf_len,strumien)!=NULL){
printf("2:\n%s\n\n",data);
msgpid.mtype=1;
if(msgsnd(mqpid,&msgpid,size1,0)==-1){perror("msgsnd failed: 1");}
msgrcv(mqpid,&msgpid,size1, 2, 0);
}
}
return 0;
}
Здесь он * снова *: 'if (feof (stdin)! = 0) printf (" \ nEnd файла \ n ");' http://stackoverflow.com/questions/5431941/why-is- while-feof-file-always-wrong 'feof()' does * not * означает end-of -file. В нем говорится, что вы пытались прочитать за пределами файла. Хотя в этом случае это кажется доброкачественным, поскольку вы использовали возвращаемое значение из 'fgets()', чтобы закончить чтение. –
@WeatherVane: Это фактически (редкое) правильное использование 'feof' - оно используется после того, как другая функция stdio уже вернула результат EOF-или-ошибки, чтобы определить, действительно ли это EOF или какая-либо другая ошибка. –
@ChrisDodd ты уверен? После достижения конца файла с помощью 'fgets() == NULL'' feof' будет недействительным, потому что код не читается за пределами конца файла.Почему это отличается от любого другого неправильного использования? –