2014-09-01 67 views
0

代碼實際做的是從父進程獲取輸入,並通過管道將其發送給子進程。子進程將其反轉,然後通過另一個管道將其發送回父進程。代碼中沒有waitpid()wait()函數。這裏發生父進程和子進程的切換?

問題是:過程切換如何在這裏工作? write()read()函數如何在這裏工作?

下面是代碼:

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

#define li long int 

using namespace std; 

void ReverseAString(char input[]) 
{ 
    li length = strlen(input),i; 
    char hold; 

    for(i=0;i<length/2;i++) 
    { 
     hold = input[i]; 
     input[i] = input[length-(i+1)]; 
     input[length-(i+1)] = hold; 
    } 
} 

int main() 
{ 
    pid_t ChildOrParentId; 
    int fifoParent[2],fifoChild[2],in; 


    if(pipe(fifoParent)==-1) 
    { 
     cout<<"Problem in creating Parent's Pipe"<<endl; 
     perror("Parent's Pipe"); 
     exit(1); 
    } 

    if(pipe(fifoChild)==-1) 
    { 
     cout<<"Problem in creating Child's Pipe"<<endl; 
     perror("Child's Pipe"); 
     exit(1); 
    } 

    ChildOrParentId = fork(); 
    if(ChildOrParentId==0) 
    { 
     char buf[100],collected[100]; 

     close(fifoParent[0]); 
     close(fifoChild[1]); 
     in = 0; 
     while(read(fifoChild[0],buf,1)>0) 
     { 
      collected[in]=buf[0]; 
      in++; 
     } 

     collected[in]=0; 
     cout<<"Read from Child "<<collected<<endl; 
     ReverseAString(collected); 
     cout<<"After Reversing: "<<collected<<endl; 

     write(fifoParent[1],collected,sizeof(collected)); 
     close(fifoParent[1]); 
    } 
    else 
    { 
     char buf[100],collected[100]; 

     close(fifoParent[1]); 
     close(fifoChild[0]); 
     in = 0; 
     cout<<"Enter a string: "; 
     gets(buf); 

     write(fifoChild[1],buf,sizeof(buf)); 
     close(fifoChild[1]); 
     while(read(fifoParent[0],buf,1)>0) 
     { 
      collected[in] = buf[0]; 
      in++; 
     } 

     collected[in] = 0; 
     cout<<"Read from Parent "<<collected<<endl; 

    } 


    return 0; 
} 

輸出窗口看起來像這樣:

Enter a string: abc // abc input given 
Read from child abc 
After reversing: cba 
Read from parent cba 
+0

你是什麼意思的「他們如何工作」? – 2014-09-01 18:45:04

+1

這是「工作」,因爲這是管道所做的 - 你爲一端寫了一些東西,然後從另一端讀取它。你在問管道是如何工作的?或者子進程如何繼承文件描述符?或者是其他東西? – 2014-09-01 18:46:23

+0

詢問「從孩子abc讀取」如何執行?上面給出的輸出是通過在父進程和子進程之間來回切換產生的......對吧?哪些陳述導致了這一點? – 2014-09-01 18:49:22

回答

1

通常,read在一個空的管直到數據可通過寫入寫入結束的管道。

因此,子進程無法繼續執行此線,直到它從父進程接收數據;它會阻止等待它:

while(read(fifoChild[0],buf,1)>0) 

一旦它讀取的字符串,它喚醒,逆轉它,並將其寫回父。家長也可能會當它達到以下行,等待子進程寫顛倒字符串阻止:

while(read(fifoParent[0],buf,1)>0) 

read阻塞行爲類似於waitwaitpid阻塞的行爲,但它等待使數據到達文件描述符,而不是等待子進程改變狀態。

一般來說,父級和子級進程同時執行,除非系統調用中一個或兩個進程被阻止。

0

當您撥打fork()時,會創建第二個進程,並且這兩個進程都位於代碼中的此位置。判斷您是新的子進程還是原始父進程的唯一方法是查看返回值fork()。在documentation中,您可以看到如果fork()返回0,那麼您處於子進程中。所以基本上,if(ChildOrParentId==0)語句的then塊只能在子進程中運行,而else塊只能在父進程中運行。

如果您將這兩個塊視爲不同的程序,其餘解釋非常簡單。父塊要求輸入一個字符串,將其發送給孩子,等待孩子發回一些東西,然後打印孩子發送的內容。同時,子塊等待來自父項的東西,打印它得到的內容,將其反轉並打印出來,然後將反轉的字符串發送回父項。