2016-03-29 142 views
0

下面是代碼:關閉管道得到錯誤的文件描述符

#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; 
} 

當我運行它,它給了我這個輸出

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

我試圖做的是創建兩個2D管道和分岔次數。 創建和運行正常,但有些管道無法關閉。 似乎p1 [i] [0]和p2 [i] [1]永遠不會更接近。

+0

提示:您正在關閉兩次,一次在循環中執行'fork',一次在以下循環中。 – isedev

+0

那麼一根管子不能關閉兩次?第二次會給出錯誤? –

+1

錯誤是EBADF,意味着該文件不是有效的_open_文件描述符。 – isedev

回答

0

您得到EBADFD的原因是您試圖關閉兩次相同的文件描述符。

我在第一個代碼片段中添加了一個print語句來顯示/跟蹤正在關閉的文件描述符。如果編譯並運行它,則會在嘗試第二次關閉描述符後看到錯誤消息。

#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; 
} 

檢查pid並關閉第一個循環內未關閉的端點。此代碼假定您正在讀取和寫入特定的管道,具體取決於孩子/家長的需要。您可能需要根據您的使用情況進行調整:

#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; 
} 
相關問題