簡體   English   中英

C未命名的管道和計算叉

[英]C unnnamed pipes and fork for calculation

因此,我正在嘗試創建一個接受用戶輸入的程序(例如,價格為50),然后第一個孩子將其傳遞給第二個,第二個孩子將其傳遞給10(價格現在為60),第三個孩子則將其添加為50(現在價格為110)和4一個只是打印/返回最終價格。 我有fork in loop,正在創建管道,但是價格始終相同,每個孩子只能添加10個。 有什么問題或如何解決,以使其能夠按我的意願工作。

我的代碼:

int main(int argc,char *argv[])
{
int anon_pipe[2];
int n,N=4;
char value_price[100];

if(argc>1)
{
    int price=atoi(argv[1]);
    printf("%d\n",price);
    if(pipe(anon_pipe)==-1){
        perror("Error opening pipe");
        return -1;
    }
    for(n = 0; n < N; n++){
        switch(fork()){
            case -1:
                perror("Problem calling fork");
                return -1;
            case 0:
                close(anon_pipe[1]);

                read(anon_pipe[0],value_price,100);

                price+=10;

                sprintf(value_price,"%d \n",price);
                printf("Price: %d\n",atoi(value_price));

                write(anon_pipe[1],value_price,sizeof(value_price));

                _exit(0);
        }
    }
    close(anon_pipe[0]);
    sleep(1);
    close(anon_pipe[1]);
}

return 0;
}

您似乎認為分叉使孩子從程序的開頭開始。 事實並非如此,分叉使子代在調用fork()時從同一行開始

例如,在此處查看以下代碼:

            read(anon_pipe[0],value_price,100);

            price+=10;

            sprintf(value_price,"%d \n",price);
            printf("Price: %d\n",atoi(value_price));

看到您增加了price的價值,但從未從管道中讀取該價值。 因此,所有子代將始終向其各自的管道輸出+10。

您應該檢查函數調用的返回值以獲取錯誤代碼。 如果已完成,則將檢測到此調用組合引起的錯誤:

            close(anon_pipe[1]);

            // ...

            write(anon_pipe[1],value_price,sizeof(value_price));

您很有可能還會檢測到許多此類呼叫...

            read(anon_pipe[0],value_price,100);

...表示文件結束而沒有讀取任何內容。 至少,您需要使用read()的返回值來確定所需的字符串終止符的放置位置(在將緩沖區用作字符串之前,您無法放置該終止符)。

通常, 必須處理read()write()的返回值,因為除了可能出現錯誤/ EOF外,這些函數還可能執行短數據傳輸而不是完整數據傳輸。 返回值告訴您已傳輸了多少字節,您需要知道該字節以確定是否循環以嘗試傳輸更多字節。

此外,您的所有進程都使用同一管道相互通信。 您可能會為此工作而感到幸運,但至少有時您最終會出現亂碼。 您確實應該為每對通信流程(包括父流程)創建一個單獨的管道。

此外,請勿使用sleep()來同步進程。 它不能可靠地工作。 相反,父級應該為其每個子進程都使用wait()waitpid() ,但只有在全部啟動它們並執行了所有需要的管道末端處理之后,才可以使用。 等待子進程還可以防止它們退出后在任何重要時間內殘留僵屍。 當主進程退出而不是繼續進行任何其他工作時(在這種情況下),這沒什么大不了的,但否則會構成資源泄漏(文件描述符)。 您應該養成等待子進程的好習慣。

當然,如果您實際上沒有寫要寫的數據,那么所有這些都是沒有意義的。 @SanchkeDellowar在他的回答中說明了您如何無法做到這一點。

暫無
暫無

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

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