Linux系統程式設計之程式間通訊方式:命名管道(一)

千鋒教育官方發表於2019-09-12

   命名管道的概述


  無名管道,由於沒有名字,只能用於親緣關係的程式間通訊(更多詳情,請看《無名管道》)。為了克服這個缺點,提出了命名管道(FIFO),也叫有名管道、FIFO檔案。


  命名管道(FIFO)不同於無名管道之處在於它提供了一個路徑名與之關聯,以FIFO的檔案形式存在於檔案系統中,這樣,即使與FIFO的建立程式不存在親緣關係的程式,只要可以訪問該路徑,就能夠彼此透過FIFO相互通訊,因此,透過FIFO不相關的程式也能交換資料。


  命名管道(FIFO)和無名管道(pipe)有一些特點是相同的,不一樣的地方在於:


  1、FIFO在檔案系統中作為一個特殊的檔案而存在,但FIFO中的內容卻存放在記憶體中。


  2、當使用FIFO的程式退出後,FIFO檔案將繼續儲存在檔案系統中以便以後使用。


  3、FIFO有名字,不相關的程式可以透過開啟命名管道進行通訊。


  命名管道的建立


  所需標頭檔案:


  #include<sys/types.h>


  #include<sys/stat.h>


  int mkfifo(const char*pathname,mode_t mode);


  功能:命名管道的建立。


  引數:


  pathname:普通的路徑名,也就是建立後FIFO的名字。


  mode:檔案的許可權,與開啟普通檔案的open()函式中的mode引數相同,相關說明請點此連結。


  返回值:


  成功:0


  失敗:如果檔案已經存在,則會出錯且返回-1。


  示例程式碼如下:


  #include<stdio.h>


  #include<sys/types.h>


  #include<sys/stat.h>


  int main(int argc,char*argv[])


  {


  int ret;


  ret=mkfifo("my_fifo",0666);//建立命名管道


  if(ret!=0){//出錯


  perror("mkfifo");


  }


  return 0;


  }


  執行結果如下:


  


  命名管道的預設操作


  後期的操作,把這個命名管道當做普通檔案一樣進行操作:open()、write()、read()、close()。但是,和無名管道一樣,操作命名管道肯定要考慮預設情況下其阻塞特性。


  下面驗證的是預設情況下的特點,即open()的時候沒有指定非阻塞標誌(O_NONBLOCK)。


  1)


  open()以只讀方式開啟FIFO時,要阻塞到某個程式為寫而開啟此FIFO


  open()以只寫方式開啟FIFO時,要阻塞到某個程式為讀而開啟此FIFO。


  簡單一句話,只讀等著只寫,只寫等著只讀,只有兩個都執行到,才會往下執行。


  只讀端程式碼如下:


  #include<stdio.h>


  #include<string.h>


  #include<unistd.h>


  #include<sys/types.h>


  #include<sys/stat.h>


  #include<fcntl.h>


  int main(int argc,char*argv[])


  {


  int fd;


  int ret;


  ret=mkfifo("my_fifo",0666);


  if(ret!=0)


  {


  perror("mkfifo");


  }


  printf("before open\n");


  fd=open("my_fifo",O_RDONLY);//等著只寫


  if(fd<0)


  {


  perror("open fifo");


  }


  printf("after open\n");


  return 0;


  }


  只寫端程式碼如下


  #include<stdio.h>


  #include<string.h>


  #include<unistd.h>


  #include<sys/types.h>


  #include<sys/stat.h>


  #include<fcntl.h>


  int main(int argc,char*argv[])


  {


  int fd;


  int ret;


  ret=mkfifo("my_fifo",0666);


  if(ret!=0)


  {


  perror("mkfifo");


  }


  printf("before open\n");


  fd=open("my_fifo",O_WRONLY);//等著只讀


  if(fd<0)


  {


  perror("open fifo");


  }


  printf("after open\n");


  return 0;


  }


  大家開啟兩個終端,分別編譯以上程式碼,讀端程式和寫端程式各自執行,如下圖,大家自行驗證其特點,因為光看結果圖是沒有效果,大家需要分析其執行過程是如何變化。


  


  如果大家不想在open()的時候阻塞,我們可以以可讀可寫方式開啟FIFO檔案,這樣open()函式就不會阻塞。


  //可讀可寫方式開啟


  int fd=open("my_fifo",O_RDWR);


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69914734/viewspace-2656892/,如需轉載,請註明出處,否則將追究法律責任。

相關文章