2016-01-23 48 views
0

在下面的程序中,我错误地在调用fork并将返回值分配给childpid(第18行)时引入了一个错误。fork()返回值bug

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块。这意味着某种程度上,childpid在父进程中从来没有被赋值> 0。这很奇怪,因为childpid初始化为-1开始,fork发生了(这就是为什么childpid在子进程中得到0值)但父进程'childpid从未得到> 0的值 - 为什么?

的修复ofcourse是围绕一个括号,这使输出的分配:

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

我知道了修复,但我是一个有点不清楚如何对自己的缺陷代码的输出解释!为什么childpid会在子进程中得到0,但在父进程中没有得到正值?

回答

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

相当于:

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

由于operator precedence==(比较)的优先级高于=(任务)。

所以childpid0除非叉两者过程()失败(在此情况下,childpid将在两个进程和if1将永远不会被执行)。因此,else块永远不会执行。

我不喜欢在if声明中使用作业。我更喜欢把它写在一个单独的行中,以便我不必始终保持运营商的优先顺序:

childpid = fork(); 

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

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

else { 
    .. 
} 
1

在马车的版本,你写

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

这首先测试如果fork()返回值是-1与否。通常,它不会(fork成功),所以它的计算结果为false。假值为0.然后将此0赋值为childpid。该计划将继续到第23行:

if(childpid == 0){ 

在这种情况下,childpid将始终为0,所以这个块总是执行,下面从来没有达到你其他块。

if语句测试是否有零(false)或非零(true)。例如:

if (0) { 

是有效的语法,并且该块永远不会被执行。另一方面,

if (1) { 

也是有效的,并将始终执行。