2016-03-29 11 views
0

Hier ist der Code:schließen Rohre bekommen Bad Dateideskriptors

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <dirent.h> 

int main(int argc, char **argv) { 

int num = 2; 
pid_t pid; 
int i; 

int p1[num][2], p2[num][2]; 
for (i = 0; i < num; i++) { 
    if (pipe(p1[i]) == -1) { 
     perror("pipe"); 
     exit(1); 
    } 
    if (pipe(p2[i]) == -1) { 
     perror("pipe"); 
     exit(1); 
    } 
} 

for (i = 0; i < num; i++) { 
    if ((pid = fork()) == 0) { 
     if (close(p1[i][1]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     if (close(p2[i][0]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     printf("%d\n", getpid()); 
     exit(0); 
    } else if (pid > 0) { 
     if (close(p1[i][0]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     if (close(p2[i][1]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     continue; 
    } else { 
     perror("fork"); 
     exit(1); 
    } 
} 

for (i = 0; i < num; i++) { 
    if (close(p1[i][0]) != 0) { 
     perror("close1"); // <----error 
    } 
    if (close(p1[i][1]) != 0) { 
     perror("close"); 
    } 
    if (close(p2[i][0]) != 0) { 
     perror("close"); 
    } 
    if (close(p2[i][1]) != 0) { 
     perror("close2"); // <----error 
    } 
} 
for (i = 0; i < num; i++) { 
    if (wait(NULL) == -1) { 
     perror("wait"); 
     exit(1); 
    } 
} 
return 0; 
} 

Als ich das laufen, es gibt mir diese Ausgabe

close1: Bad file descriptor 
close2: Bad file descriptor 
close1: Bad file descriptor 
close2: Bad file descriptor 
8798 
8799 

Was ich versuche zwei 2D zu tun ist, zu schaffen Array von Rohren und Gabelnummern. Das Erstellen und Ausführen funktioniert gut, aber einige Pipes können nicht geschlossen werden. Es scheint, dass p1 [i] [0] und p2 [i] [1] niemals näher beieinander liegen.

+0

Hinweis: Sie schließen zweimal, einmal in der Schleife tun die Gabel und einmal in der folgenden Schleife. – isedev

+0

So ein Rohr kann nicht zweimal geschlossen werden? Das zweite Mal gibt einen Fehler? –

+1

Der Fehler ist EBADF, was bedeutet, dass die Datei kein gültiger _open_Dateideskriptor ist. – isedev

Antwort

0

Der Grund, warum Sie die EBADFD erhalten, ist, dass Sie versuchen, den gleichen Dateideskriptor zweimal zu schließen.

Ich habe eine Druckanweisung in diesem ersten Codeschnipsel hinzugefügt, um anzuzeigen/zu verfolgen, welcher Dateideskriptor geschlossen wird. Wenn Sie das kompilieren und ausführen, sehen Sie, dass die Fehlermeldung angezeigt wird, nachdem Sie versucht haben, den Deskriptor ein zweites Mal zu schließen.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <dirent.h> 

int main(int argc, char **argv) { 

int num = 1; 
pid_t pid; 
int i; 

int p1[num][2], p2[num][2]; 
for (i = 0; i < num; i++) { 
    if (pipe(p1[i]) == -1) { 
     perror("pipe"); 
     exit(1); 
    } 
    if (pipe(p2[i]) == -1) { 
     perror("pipe"); 
     exit(1); 
    } 
} 

for (i = 0; i < num; i++) { 
    if ((pid = fork()) == 0) { 
     printf("Child closing: Pipe1 %d End %d\n", i, 1); 
     if (close(p1[i][1]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     printf("Child closing: Pipe2 %d End %d\n", i, 1); 
     if (close(p2[i][0]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     printf("%d\n", getpid()); 
     exit(0); 
    } else if (pid > 0) { 
     printf("Parent closing: Pipe1 %d End %d\n", i, 0); 
     if (close(p1[i][0]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     printf("Parent closing: Pipe1 %d End %d\n", i, 1); 
     if (close(p2[i][1]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     continue; 
    } else { 
     perror("fork"); 
     exit(1); 
    } 
} 

for (i = 0; i < num; i++) { 
    printf("Closing: Pipe1: %d End: %d\n", i, 0); 
    if (close(p1[i][0]) != 0) { 
     perror("close1"); // <----error 
    } 
    printf("Closing: Pipe1: %d End: %d\n", i, 1); 
    if (close(p1[i][1]) != 0) { 
     perror("close"); 
    } 
    printf("Closing: Pipe2: %d End: %d\n", i, 0); 
    if (close(p2[i][0]) != 0) { 
     perror("close"); 
    } 
    printf("Closing: Pipe2: %d End: %d\n", i, 1); 
    if (close(p2[i][1]) != 0) { 
     perror("close2"); // <----error 
    } 
} 
for (i = 0; i < num; i++) { 
    if (wait(NULL) == -1) { 
     perror("wait"); 
     exit(1); 
    } 
} 
return 0; 
} 

prüfen für die pid und die Enden schließen, die nicht in Ihrem ersten Schleife geschlossen wurden. In diesem Code wird davon ausgegangen, dass Sie eine bestimmte Pipe lesen und auf diese schreiben, je nach dem Bedarf des Kindes/Elternteils. Möglicherweise müssen Sie jedoch anpassen, wie Ihr Anwendungsfall vorschreibt:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <dirent.h> 

int main(int argc, char **argv) { 

int num = 1; 
pid_t pid; 
int i; 

int p1[num][2], p2[num][2]; 
for (i = 0; i < num; i++) { 
    if (pipe(p1[i]) == -1) { 
     perror("pipe"); 
     exit(1); 
    } 
    if (pipe(p2[i]) == -1) { 
     perror("pipe"); 
     exit(1); 
    } 
} 

for (i = 0; i < num; i++) { 
    if ((pid = fork()) == 0) { 
     if (close(p1[i][1]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     if (close(p2[i][0]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     printf("%d\n", getpid()); 
     exit(0); 
    } else if (pid > 0) { 
     if (close(p1[i][0]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     if (close(p2[i][1]) != 0) { 
      perror("close"); 
      exit(1); 
     } 
     continue; 
    } else { 
     perror("fork"); 
     exit(1); 
    } 
} 

for (i = 0; i < num; i++) { 
    if (pid == 0) { 
     if (close(p1[i][0]) != 0) { 
      perror("close1"); 
     } 
     if (close(p2[i][1]) != 0) { 
      perror("close"); 
     } 
    } else { 
     if (close(p1[i][1]) != 0) { 
      perror("close"); 
     } 
     if (close(p2[i][0]) != 0) { 
      perror("close2"); 
     } 
    } 
} 
for (i = 0; i < num; i++) { 
    if (wait(NULL) == -1) { 
     perror("wait"); 
     exit(1); 
    } 
} 
return 0; 
}