2012-11-07 63 views
1

我搜查了無法找到,所以我終於來求助了。 我的任務涉及(在RedHat Linux上運行的C語言中)創建兩個子進程,每個子進程都將任意數量的迭代字符寫入管道。該管道與創建它們的父進程共享。父母從管道讀取,而孩子仍然有字符寫入。一旦孩子退出並且管道是空的,父母(主)就可以終止。2個孩子寫信給管道,家長從管道中讀取C

這是我寫的代碼邏輯的一個很快的&髒例子。

main() 
{ 
     //create pipe 

     fork(); //childA 
     //writes to pipe 

     fork(); //childB 
     //writes to pipe 

     //parent reading 
     while(condition) { 
      //read from pipe + print chars to terminal 
     } 
} 

現在,我的問題是關於while循環的條件。 我需要閱讀時,由於一個完整的管道阻止孩子寫作,但我無法弄清楚什麼樣的條件會允許我這樣做。任何幫助將是絕對驚人的。

+0

你應該總是閱讀:這是擺脫「滿管」狀態的唯一方法。一旦最後一個孩子關閉管道,read將返回-1。 – wildplasser

+0

@wildplasser'read'在文件結束時返回0,錯誤時返回-1;所以當最後一個孩子關閉管道並且沒有數據需要讀取時它將返回0。 'fread'返回一個小於你請求的對象數(或0)的值,並且你需要使用'feof'和'ferror'來確定你是否有文件結尾或錯誤。 –

回答

0

閱讀時是否要求管道滿管?或者,是否僅僅是一個要求,即使其中一個管道已滿,孩子在寫作時被阻止,你還是繼續讀兩個孩子?

我不知道任何標準的方式來如果管道滿了高。您可以嘗試使用ioctl來確定需要在管道上讀取多少數據,然後將其與PIPE_BUF進行比較,但如果管道中的數據少於PIPE_BUF,但該子數據庫正在執行寫操作,則可能無法正常工作那會超過PIPE_BUF;該呼叫可能會阻塞而不填滿管道。我不會依賴這種技術工作。

從兩個文件描述符(不管哪一個已準備好)讀取的通常方法是使用select系統調用。這允許您等待一個或另一個文件描述符具有可用數據。這意味着父進程不會阻止嘗試從一個沒有任何可用數據的孩子讀取數據,而另一個孩子因爲緩衝區已滿而被阻塞。

編輯:重新讀你的問題後,它聽起來像實際上只有一個管道,這兩個孩子正在寫信給。那是對的嗎?再次,問題出現在你是否需要等到孩子們被阻止。如果家長只是從管道讀取數據,它將阻塞,直到其中一個孩子寫入管道;你不需要做任何特別的事情。

如果您的任務需要您等待,直到管道實際上已滿,我會有興趣看到確切的措辭,因爲我不知道爲什麼要這樣做。

編輯2:在回答你的問題在註釋:

  1. 確實爲我的父進程的代碼需要遵循的代碼在程序中我的兩個子進程?

    不,沒有關於父或子進程的代碼順序的要求。爲了區分父代碼和子代碼運行的代碼,您需要檢查返回值fork()。如果返回值爲0,那麼您處於子進程中。如果不是,你就在父母身邊;如果返回值是-1,那麼出現錯誤,如果它是正數,則它是子進程的PID。

    所以,你可以寫這樣的代碼:

    int pid = fork(); 
    if (pid) { 
        // in the parent, check if pid is -1 for errors 
    } else { 
        // in the child 
    } 
    

    或者:

    int pid = fork(); 
    if (pid == 0) { 
        // in the child, do whatever you need to do and... 
        exit(0); 
    } 
    
    // in the parent; since the child calls exit() above, control will never 
    // reach here in the child. Or you could do an execl() in the child, which 
    // replaces the current program with another one, so again, control will 
    // never reach here within the child process. 
    
  2. 我怎能從管道讀取,直到兩個孩子終止,管道是空?

    只要繼續讀書,直到,直到所有進程都關閉了管道的寫入結束read回報在管道的讀端0 read將不會返回0,並且所有的數據已讀出的管道。如果某些東西仍然打開,但管道中沒有數據,則read將阻塞,直到數據寫入管道。

    一個問題是要記住在嘗試read之前關閉父進程中管道的寫入結束;否則,當父母在孩子完成後試圖執行read時,它將阻止等待它關閉自己的管道。

+0

事實上,只有一條管道,這兩個孩子正在寫信給父母,並正在閱讀。 好吧,分配狀態的要求,父母從管道讀取每次讀取100個字符,然後將所述字符打印到終端。這樣做直到每個孩子已經完成其每個迭代(childA = 900次迭代,childB = 260次迭代)。 我想我不必等到孩子們被阻塞,但是我確實需要在每次讀取時從管道讀取100個字符。 – user1807614

+0

我想我的主要問題是: 1.我的父進程的代碼是否需要遵循程序內我的兩個子進程的代碼? 2.我怎樣才能繼續閱讀管道,直到兩個孩子終止並且管道是空的? – user1807614

+0

@ user1807614我在回答中解答了您的問題 –