2014-03-19 149 views
0

我想讓父進程和子進程在C linux中使用管道進行通信。首先,我希望父母傳遞一個字符串,然後讓孩子承認它。我創建了兩個文件描述符。一個用於父母對孩子,即讀音管和其他用於反義詞的書寫管。問題是它沒有把我的數據作爲輸入。另外,我希望printf語句(如「輸入數據」)可以打印一次,但自fork之後,有兩個進程會顯示兩次。任何替代方案?在C linux中使用管道的雙向通信

//readpipe[0] = child read 
//readpipe[1]= parent write 

//writepipe[0]=parent read 
//writepipe[1]=child write 

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

int main(void) 
{ 
     pid_t pid; 
     int r; 
     /* Hope this is big enough. */ 
    char buf[1024]; 
    char cp[50]; 
    char ans; 
    int readpipe[2]; 
    int writepipe[2]; 
    int a; 
    int b; 
    a=pipe(readpipe); 
    b=pipe(writepipe); 
    if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); } 
    if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); } 

    printf("\nSEND SOMETHING TO CHILD PROCESS\t"); 
    scanf(" %c",&ans); 
    pid=fork(); 
    if(pid==-1) 
    { 
     printf("pid:main"); 
     exit(1); 
    } 

    while(ans=='y' || ans=='Y') 
    { 
     printf("\nEnter data\t"); //printed twice 
     fgets(cp, 50, stdin);  //not taking data 
     printf("\n%s",cp);   
     if(pid==0) 
     { //CHILD PROCESS 
     close(readpipe[1]); 
     close(writepipe[0]); 
     read(readpipe[0],buf,sizeof(buf)); 
     printf("\nSENT\n %s",buf); 
     write(writepipe[1],cp,strlen(cp)+1); 
     } 
     else 
     { //PARENT PROCESS 
     close(readpipe[0]); 
     close(writepipe[1]); 
     write(readpipe[1],cp,strlen(cp)+1); 
     read(writepipe[0],buf,sizeof(buf)); 
     printf("\nRECEIVED\n %s",buf); 
    } 
    printf("\nSEND SOMETHING TO CHILD PROCESS\t"); 
    scanf(" %c",&ans); 
    } 
    close(readpipe[1]); 
    close(writepipe[0]); 
    close(readpipe[0]); 
    close(writepipe[1]); 

    return 0; 
} 
+0

如果你不復如[poll(2)](http://man7.org/linux/man-pages/man2/poll.2.html),你將面臨互相飢餓的僵局(每個進程都被阻塞,等待另一個輸出)。 –

回答

0
  1. 爲什麼fgets沒有獲取數據? 在第一scanf函數,你正在閱讀的單個字符和新的生產線仍將是
    輸入緩衝器,這將使跳過

    爲了解決這個問題,你應該使用的scanf(「%[^ \ n]的%* C」,& ANS) - 參考this更多細節

  2. 查找修改後的代碼..它可能對你有所幫助(從我做了一些改變,而在打破和我驗證的基本功能)

int主要(無效){

pid_t pid; 
int r; 
/* Hope this is big enough. */ 
char buf[1024]; 
char cp[50]; 
char ans; 
int readpipe[2]; 
int writepipe[2]; 
int a; 
int b; 
a=pipe(readpipe); 
b=pipe(writepipe); 
if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); } 
if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); } 

printf("\nSEND SOMETHING TO CHILD PROCESS\t"); 
scanf("%[^\n]%*c",&ans); 
//ans = getchar(); 
fflush(stdin); 
pid=fork(); 
if(pid==-1) 
{ 
    printf("pid:main"); 
    exit(1); 
} 

while(ans=='y' || ans=='Y') 
{ 
    if(pid==0) 
    { 
     //CHILD PROCESS 
     close(readpipe[1]); 
     close(writepipe[0]); 
     if(read(readpipe[0],buf,sizeof(buf)) < 0) 
     { 
      break; 
     } 

     printf("\nChild Process Read: %s\n",buf); 

     printf("\n(child)Enter data:\t"); //printed twice 
     fgets(cp, 50, stdin);  //not taking data 
     printf("\nData Written to Parent%s",cp); 
     if(!strncmp("Q",cp,1) || write(writepipe[1],cp,strlen(cp)+1) < 0) 
     { 
      break; 
     } 
    } 
    else 
    { 
     //PARENT PROCESS 
     close(readpipe[0]); 
     close(writepipe[1]); 
     printf("\n(Parent)Enter data\t"); //printed twice 
     fgets(cp, 50, stdin);  //not taking data 

     printf("\nData Writtent to Child: %s",cp); 
     if(!strncmp("Q",cp,1) || write(readpipe[1],cp,strlen(cp)+1) < 0) 
     { 
      break; 
     }   

     if(read(writepipe[0],buf,sizeof(buf)) < 0) 
     { 
      break; 
     } 
     printf("\nParent Process Read: %s\n",buf); 
    } 
    ans ='y'; 
} 

close(readpipe[1]); 
close(writepipe[0]); 
close(readpipe[0]); 
close(writepipe[1]); 
return 0; 

}

+0

謝謝先生。但是,請您介紹一下函數strncmp。程序中的「Q」是什麼,以及你爲什麼在這裏使用它? – user3436838

+0

我已經添加了這個邏輯來打破while循環,如果你輸入Q.那麼strncmp會通過,它會打破while循環,它將退出程序..如果它不乾淨..你可以選擇一些更好的方法.. –

+0

好的。這很清楚。萬分感謝..:) – user3436838

1

你叫

printf("\nEnter data\t"); //printed twice 
    fgets(cp, 50, stdin);  //not taking data 

之前您檢查是否是在父或子進程。這當然會導致兩個進程都打印出來,並且都會讀取標準輸入。所以目前還不清楚哪個進程讀取你輸入的日期。

同樣的問題會發生在這些線路:

printf("\nSEND SOMETHING TO CHILD PROCESS\t"); 
scanf(" %c",&ans); 

我建議你重新設計你的程序,在父進程中運行afrer fork(),在子進程的運行顯然獨立的代碼和代碼。