2015-11-04 39 views
1

即時通訊嘗試在我的程序中使用pipe,fork和dup.i執行md5sume命令,發現代碼運行成功,但我無法理解一些代碼行。這裏是我的代碼:popen2()如何在c中工作?

int infp, outfp; 

char buf[128]; 

if (popen2("md5sum", &infp, &outfp) <= 0) 

    { 

    printf("Unable to exec sort\n"); 

    exit(1); 

    } 

write(infp, "hello\n", 2); 

close(infp); 

*buf = '\0'; 

read(outfp, buf, 128); 

printf("buf = '%s'\n", buf); 

return 0; 

} 

int p_stdin[2], p_stdout[2]; 

pid_t pid; 

if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0) 

    return -1; 

pid = fork(); 

if (pid < 0) 

    return pid; 

if (pid == 0) 

    { 

    close(p_stdin[WRITE]); 

    dup2(p_stdin[READ], READ); 

    close(p_stdout[READ]); 

    dup2(p_stdout[WRITE], WRITE); 

    execl("/bin/sh", "sh", "-c", command, NULL); 

    perror("execl"); 

    exit(1); 

    } 

else 

    { 

if (infp == NULL) 

    close(p_stdin[WRITE]); 

else 

    *infp = p_stdin[WRITE]; 

if (outfp == NULL) 

    close(p_stdout[READ]); 

else 

    *outfp = p_stdout[READ]; 
    } 

return pid; 

} 

我不明白的POPEN功能。這條線究竟幹什麼?

*infp = p_stdin[WRITE]; 

管道怎麼能相互交流?

+2

格式化您的代碼!刪除不必要的空行。 – Olaf

+1

你說的是'popen2()'不是'popen()'我猜。我也猜測第二個代碼塊是'popen2()'函數。你應該參考'man 2 pipe'並閱讀描述。管道由2個文件描述符表示,一個用於寫入,另一個用於讀取。你可以從中讀取你寫的內容。 fork()後,其中一個進程可以寫入,另一個從中讀取,以便進行通信。 – hexasoft

+0

嗯,我知道這一點,並且我知道這是popen2函數,但我不能理解使用整數來實現雙向管道,而且它不在人類! – farzane

回答

1

我不明白popen功能。

管道怎麼能相互交流?

pipe():管道是內核中的單向和字節流緩衝區。由於它是字節流類型,寫入者可以寫入任意數量的字節,讀取器可以讀取任意數量的字節。但是,請注意順序讀取是可能的,但尋找(如lseek)是不可能的。由於管道是單向的,因此寫入管道的數據應緩存在內核中,直到從管道的讀端讀取。另外,如果管道已滿,寫入塊。我們認爲fd是一個由2個文件描述符(int fd [2])組成的整數數組,然後pipe(fd)系統調用將創建一個管道並返回一對文件描述符,使得fd [1](標準輸出爲1)應爲管道的寫端,而fd [0](標準輸入爲0)應爲管道的讀端。與命名管道不同(例如FIFO--在File系統中具有名稱的管道),匿名管道只能在相關進程(如父 - 子)之間使用。因此,fork必須在子進程中複製這兩個父文件描述符,因此父進程與子進程共享管道,以便子進程寫入結束,並且父進程應從管道讀端進行讀取,或者父進程應寫入寫入結束, end和child應從管道的讀端讀取。應該注意確保根據場景關閉父節點或子節點未使用的讀取(fd [0])文件描述符/未使用的寫入(fd [1])文件描述符。

popen(): popen使您可以調用另一個程序作爲新進程,從而向其傳輸數據或從其接收數據。在popen的情況下,請注意數據流的方向基於第二個參數。我們不需要手動創建一個子進程作爲popen自動分支來創建一個子進程,啓動一個shell並執行通過popen傳遞的命令參數。它還基於類型自變量自動在父代和子代之間建立適當的讀取或寫入流。

因此,popen()簡化了事情,因爲它避免了手動調用/調用pipe,fork,exec並根據參數類型自動簡化在父/子之間建立適當流的需要。然而,popen的另一方面是,應該注意的是,每次調用popen()都會導致創建額外的進程 - 也就是說,除了正在調用的程序之外,每次調用shell時,轉向導致高資源消耗。

+0

我知道這個。我的主要問題是關於雙向管道。你知道在popen中我們可以在第二個參數中設置w或r心情,但在我的程序中我需要使用rw mood.so,我需要雙向管道! – farzane

+0

管道是單向的。 popen僅支持'r'或'w',並且不支持其他選項,例如'讀寫'。在使用管道進行雙向通信的情況下,您可能需要實施兩根管道,以便每個方向都有一根管道。 –