2014-01-24 83 views
0

我想不通爲什麼我可以成功地通過一個叉但不通過2.第一個例子給出了等效於「ps -A | grep bash」的預期輸出,第二個例子應該給出「ps -A | grep bash | wc -l」的輸出,它只是第一個輸出產生的行數。相反,它沒有輸出,只是掛起。管道stdin /通過多叉叉out

這工作:

#include <iostream> 
#include <string> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h>  

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    int p1[2], p2[2];    
    pipe(p1); pipe(p2);    
    pid_t pID; 

    pID = fork(); 

    if (pID == 0)  
    { 
     close(p2[0]);        
     dup2(p2[1], 1);      
     close(p2[1]);      
     execlp("ps", "ps", "-A", 0);  // print all processes 
    } 
    else 
    { 
     wait(pID);       
     close(p2[1]);      
     dup2(p2[0],0);      
     close(p2[0]);      
     execlp("grep", "grep", "bash", NULL); // search for bash (in process list) 
    } 
} 

但這並不:

#include <iostream> 
#include <string> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h>  

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    int p1[2], p2[2];    
    pipe(p1); pipe(p2);    
    pid_t pID; 

    pID = fork(); 

    if (pID == 0)  
    { 
     pID = fork(); 

     if (pID == 0) 
     { 
      close(p2[0]);        
      dup2(p2[1], 1);      
      execlp("ps", "ps", "-A", 0);  // print all processes 
     } 
     else 
     { 
      wait(pID);       
      close(p2[1]);      
      dup2(p2[0],0);      
      close(p1[0]);        
      dup2(p1[1], 1);      
      execlp("grep", "grep", "bash", 0); // search for bash (in process list) 
     } 
    } 
    else 
    { 
     wait(pID); 
     close(p1[1]);      
     dup2(p1[0],0);      
     execlp("wc", "wc", "-l", 0);   // count lines 
    } 
} 
+4

有很多相關的問題。簡短的答案是你沒有關閉足夠多的文件描述符。在對dup2()進行適當調用後,三個進程中的每一個都應該關閉4個管道描述符。如果你不這樣做,那麼'grep'的標準輸入有兩個進程仍然可以寫入('grep'和'wc'),所以'grep'永遠不會得到EOF,所以'wc'永遠不會得到EOF ,所以一切都是穩定的。 –

+1

不要在level0處啓動所有管道,在level1處定義p1;並在第二級P2,並解決問題。除此之外,不要混合使用C&C++的東西... – moeCake

+0

@moeCake,謝謝,那就是訣竅。 – Tyler

回答

1

由於moeCoke和Leffeir說,如果你在你的代碼改變單一的線,它的工作原理精絕。

#include <iostream> 
#include <string> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h>  

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    int p1[2], p2[2];    
    pipe(p1);    
    pid_t pID; 

    pID = fork(); 

    if (pID == 0)  
    { 
     pipe(p2); // <-- call pipe for p2 here --- 
     pID = fork(); 

     if (pID == 0) 
     { 
      close(p2[0]);        
      dup2(p2[1], 1);      
      execlp("ps", "ps", "-A", 0);  // print all processes 
     } 
     else 
     { 
      wait(pID);       
      close(p2[1]);      
      dup2(p2[0],0);      
      close(p1[0]);        
      dup2(p1[1], 1);      
      execlp("grep", "grep", "p", 0); // search for bash (in process list) 
     } 
    } 
    else 
    { 
     wait(pID); 
     close(p1[1]);      
     dup2(p1[0],0);      
     execlp("wc", "wc", "-l", 0);   // count lines 
    } 
}