簡體   English   中英

fork()返回值錯誤

[英]fork() return value bug

在下面的程序中,我在調用fork並將返回值分配給childpid時錯誤地引入了一個錯誤(第18行)。

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 #include <stdlib.h>
  5 #include <string.h>
  6
  7 int main(){
  8
  9         int     fd[2], nbytes;
 10         pid_t   childpid = -1;
 11         char    string[] = "Hello, world!";
 12         char    readbuffer[80];
 13
 14         pipe(fd);
 15         printf("Parent: Beginning of Program...\n");
 16
 17
 18         if(childpid = fork() == -1){  // BUG-FIX: Missing parenthesis (childpid=fork())==-1
 19                 printf("childpid == -1\n");
 20                 perror("fork");
 21                 exit(1);
 22         }
 23         if(childpid == 0){
 24                 // child process closes up input of pipe
 25                 close(fd[0]);
 26
 27                 // send string through output side of pipe
 28                 write(fd[1], string, (strlen(string)+1));
 29                 printf("Child %d: Finished writing to pipe!\n",childpid);
 30                 exit(0);
 31         }
 32         else{
 33                 // parent closes output side of pipe
 34                 close(fd[1]);
 35
 36                 // read in a string from the pipe
 37                 nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
 38                 printf("Parent %d: Received string: %s\n", childpid,readbuffer);
 39         }
 40
 41
 42         printf("Parent %d: End of program\n", childpid);
 43         return 0;
 44 }

越野車的輸出為:

$ ./a.exe
Parent: Beginning of Program...
Child 0: Finished writing to pipe!

多次運行它,我發現else塊從未到達。 這意味着子進程永遠不會在父進程中被分配大於0的值。 這很奇怪,因為childpid首先被初始化為-1,所以確實發生了fork(這就是為什么childpid在子進程中的值為0),但是父進程的childpid從未得到的值> 0-為什么呢?

當然,解決方法是用圓括號括住該賦值,從而使輸出為:

$ ./a
Parent: Beginning of Program...
Parent 106648: Received string: Hello, world!
Child 0: Finished writing to pipe!
Parent 106648: End of program

我知道解決方法,但是我不清楚如何向我解釋錯誤代碼的輸出! 為什么childpid在子進程中會得到0,而在父進程中卻沒有得到正值?

  if(childpid = fork() == -1){  

等效於:

  if(childpid = (fork() == -1) ){  

由於運算符優先 == (比較)的優先級高於= (分配)。

因此,除非fork()失敗,否則兩個進程中的childpid 均為 0 (在這種情況下,兩個進程中的childpid均為1 ,並且if塊將永遠不會執行)。 因此,永遠不會執行else塊。

我不是在if語句中使用賦值的忠實擁護者。 我更喜歡將其寫在單獨的一行中,這樣我就不必一直將運算符的優先級放在腦海中:

childpid = fork();

 if(childpid  == -1){  
   /* error */
}

if ( childpid == 0) {
  ...
}

else {
  ..
}

在越野車版本中,您寫道

    if(childpid = fork() == -1)

這首先測試fork()的返回值是否為-1。 通常不會(派生成功),因此它的計算結果為false。 假值為0。然后將此0分配給childpid 程序繼續到第23行:

    if(childpid == 0){

在這種情況下, childpid將始終為0,因此將始終執行此塊,而不會到達下面的else塊。

if語句測試某些東西是零(假)還是非零(真)。 例如:

    if ( 0 ) {

是有效的語法,該塊將永遠不會執行。 另一方面,

    if ( 1 ) {

也有效,並且將始終執行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM