minix管道實現小究

在考研複習時候遇到的問題,很想寫下來,雖然時間已經很緊張,但是在我們師生的問答互助之間,學術似乎更顯神聖了,比起骯髒的考試製度來說……(請配合代碼看)

問題表述:

      在minix裏面,使用如下命令會使系統在2個進程之間建立管道用來進行進程之間的通訊:

      #cat file1 file2|sort

     那麼它的作用顯而易見,列出file1和2的內容並排序放入另一文件。那麼在內核當中是如何實現的呢?道理很簡單,這條指令被shell接受以後會產生一個系統調用sys_call,名字是PIPE。調用的格式首先是使用庫函數(minix的系統調用使用庫函數)pipe(&fd[0]);其中fd[ ]這個數組的聲明是這樣子的:

int fd[2]

它是文件引用的數組,由於在2個進程當中,所以對文件使用2個引用定向到不同進程的輸入輸出就可以了。那麼pipe建好了,其內容就是一個內存塊m(實際上是消息機制的消息結構塊,m_i1,m_i2),m的2個域賦值給fd的2個cell,當然一讀一寫。好,然後我們開始fork系統調用,這次我們會得到2個進程,一對父子。下面我們假設從父親發出信息,兒子取消息。我們會怎麼做呢?

問題解決:

1.我們會關閉管道的讀寫,以備下面給父子分配讀寫引用

2.父子進程會由管道方向安排讀寫的放棄,例如,在這裏,父親放棄讀引用STD_OUTPUT,兒子自然放棄

   STD_INPUT,注意,這個時候有一個關鍵問題,也是我誤解的問題,文件下面會使用dup函數重新連接2個

   引用,機制是選擇文件描述符的整數值最低的1個。那麼文件描述符究竟是怎麼分配的呢?經過林老師的指點

   發現在每個進程有3個文件引用0-stdin,1-stdout,2-stderr,那麼放棄1的父親和放棄0的兒子就會分別

   將新的文件引用dup到1和0上面

3.自然就是dup掛接引用了。注意dup裏面使用了fcntl所以你將看到這個連接的方式就是從0開始找到最小的

空閒的描述連接他。至此pipe就建立了。特嫩鮑姆說他的minix的pipe最大時4096+3072,並且可以自行分配

空間大小,如果溢出,就會在loop當中死鎖,這是顯然的,呵呵。

#include STD_INPUT 0
#include STD_OUTPUT 1
 

 pipeline(process1,porcess2)
 char *process1,*process2;//舊的C標準參數聲明吧~~~~~
 {
  int fd[2]; //存儲讀寫的文件引用
  
  pipe(&fd[0]);//create a pipe
  if(fork()!=0){
    //父進程的語句
    close(fd[0]);   //關閉管道讀
    close(STD_OUTPUT);
   dup(fd[1]);   //標準輸出指向fd[1] 

/*===============================================================================

/*這裏是dup的原形*/

PUBLIC int dup(fd)
{
  return(fcntl(fd,F_DUPFD,0));
}

==============================================================================*/  
    close(fd[1]);  //不再需要描述符
   execl(process1,process1,0);
   }
   else
   {
     //子進程的代碼
    close(fd[1]);
    close(STD_INPUT);
   dup(fd[0]);
    close(fd[0]);
  execl(process2,process2,0);
  }
 }
 //===========================================================================================

copyright of all code used in this text belongs to Dr.Andrew S. Tanenbaum

thank you very much.

鳴謝:我的老師 林豐波先生,感謝他在百忙之中回答我的問題。

最後,祝願包括自己在內天下考研同學成功~~~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章