最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

linux編程之pipe()函數(shù)詳解

 更新時間:2016年11月23日 08:43:19   作者:流云攬月  
本篇文章主要介紹了linux編程之pipe()函數(shù)詳解,具有一定的參考價值,有需要的可以了解一下。

管道是一種把兩個進程之間的標準輸入和標準輸出連接起來的機制,從而提供一種讓多個進程間通信的方法,當進程創(chuàng)建管道時,每次都需要提供兩個文件描述符來操作管道。其中一個對管道進行寫操作,另一個對管道進行讀操作。對管道的讀寫與一般的IO系統(tǒng)函數(shù)一致,使用write()函數(shù)寫入數(shù)據,使用read()讀出數(shù)據。

#include<unistd.h>

int pipe(int filedes[2]);

返回值:成功,返回0,否則返回-1。參數(shù)數(shù)組包含pipe使用的兩個文件的描述符。fd[0]:讀管道,fd[1]:寫管道。

必須在fork()中調用pipe(),否則子進程不會繼承文件描述符。兩個進程不共享祖先進程,就不能使用pipe。但是可以使用命名管道。


當管道進行寫入操作的時候,如果寫入的數(shù)據小于128K則是非原子的,如果大于128K字節(jié),緩沖區(qū)的數(shù)據將被連續(xù)地寫入管道,直到全部數(shù)據寫完為止,如果沒有進程讀取數(shù)據,則將一直阻塞,如下:

在上例程序中,子進程一次性寫入128K數(shù)據,當父進程將全部數(shù)據讀取完畢的時候,子進程的write()函數(shù)才結束阻塞并且

返回寫入信息。

命名管道FIFO

管道最大的劣勢就是沒有名字,只能用于有一個共同祖先進程的各個進程之間。FIFO代表先進先出,單它是一個單向數(shù)據流,也就是半雙工,和

管道不同的是:每個FIFO都有一個路徑與之關聯(lián),從而允許無親緣關系的進程訪問。       

#include <sys/types.h>

    #include <sys/stat.h>

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

這里pathname是路徑名,mode是sys/stat.h里面定義的創(chuàng)建文件的權限.

有親緣關系進程間的fifo的例子

/*
 * 有親緣關系的進程間的fifo的使用
 * fifo 使用的簡單例子
 */

#include "../all.h"

#define FIFO_PATH "/tmp/hover_fifo"


void 
do_sig(int signo)
{
  if (signo == SIGCHLD)
    while (waitpid(-1, NULL, WNOHANG) > 0)
      ;
}


int
main(void)
{
  int ret;
  int fdr, fdw;
  pid_t pid;

  char words[10] = "123456789";
  char buf[10] = {'\0'};  
  
  // 創(chuàng)建它,若存在則不算是錯誤,
  // 若想修改其屬性需要先打開得到fd,然后用fcntl來獲取屬性,然后設置屬性.

  if (((ret = mkfifo(FIFO_PATH, FILE_MODE)) == -1) 

           && (errno != EEXIST))
    perr_exit("mkfifo()");
  fprintf(stderr, "fifo : %s created successfully!\n", FIFO_PATH);

  signal(SIGCHLD, do_sig);

  pid = fork();
  if (pid == 0) { // child

    if ((fdr = open(FIFO_PATH, O_WRONLY)) < 0) // 打開fifo用來寫
      perr_exit("open()");
    sleep(2);

    // 寫入數(shù)據
    if (write(fdr, words, sizeof(words)) != sizeof(words)) 
      perr_exit("write");
    fprintf(stderr, "child write : %s\n", words);
    close(fdw);
  } else if (pid > 0) { // parent

    if ((fdr = open(FIFO_PATH, O_RDONLY)) < 0) // 打開fifo用來讀

      perr_exit("open()");

    fprintf(stderr, "I father read, waiting for child ...\n");
    if (read(fdr, buf, 9) != 9) //讀數(shù)據
      perr_exit("read");

    fprintf(stderr, "father get buf : %s\n", buf);
    close(fdr);
  }
  // 到這里fifo管道并沒有被刪除,必須手動調用函數(shù)unlink或remove刪除.

  return 0;  
}

 從例子上可以看出使用fifo時需要注意:

*fifo管道是先調用mkfifo創(chuàng)建,然后再用open打開得到fd來使用.

*在打開fifo時要注意,它是半雙工的的,一般不能使用O_RDWR打開,而只能用只讀或只寫打開.

fifo可以用在非親緣關系的進程間,而它的真正用途是在服務器和客戶端之間. 由于它是半雙工的所以,如果要進行客戶端和服務器雙方的通信的話,

每個方向都必須建立兩個管道,一個用于讀,一個用于寫.

下面是一個服務器,對多個客戶端的fifo的例子:

server 端的例子:

/*
 * FIFO server
 */

#include "all.h"

int
main(void)
{
  int fdw, fdw2;
  int fdr;
  char clt_path[PATH_LEN] = {'\0'};
  char buf[MAX_LINE] = {'\0'};
  char *p;
  int n;
  
  if (mkfifo(FIFO_SVR, FILE_MODE) == -1 && errno != EEXIST)  
    perr_exit("mkfifo()");  
  if ((fdr = open(FIFO_SVR, O_RDONLY)) < 0)  
    perr_exit("open()");
  /* 
   * 根據fifo的創(chuàng)建規(guī)則, 若從一個空管道或fifo讀, 

   * 而在讀之前管道或fifo有打開來寫的操作, 那么讀操作將會阻塞 
   * 直到管道或fifo不打開來讀, 或管道或fifo中有數(shù)據為止. 

   *

   * 這里,我們的fifo本來是打開用來讀的,但是為了,read不返回0,

   * 讓每次client端讀完都阻塞在fifo上,我們又打開一次來讀.
   * 見unpv2 charper 4.7
   */
  if ((fdw2 = open(FIFO_SVR, O_WRONLY)) < 0)  
    fprintf(stderr, "open()");
  
  while (1) {
    /* read client fifo path from FIFO_SVR */

   /* 這里由于FIFO_SVR有打開來寫的操作,所以當管道沒有數(shù)據時, 

   * read會阻塞,而不是返回0. 

   */
    if (read(fdr, clt_path, PATH_LEN) < 0) {
      fprintf(stderr, "read fifo client path error : %s\n", strerror(errno));  
      break;
    }
    if ((p = strstr(clt_path, "\r\n")) == NULL) {
      fprintf(stderr, "clt_path error: %s\n", clt_path);
      break;
    }
    *p = '\0';
    DBG("clt_path", clt_path);
    if (access(clt_path, W_OK) == -1) { // client fifo ok, but no permission

      perror("access()");  
      continue;
    }
    /* open client fifo for write */
    if ((fdw = open(clt_path, O_WRONLY)) < 0) {
      perror("open()");  
      continue;
    }
    if ((n = read(fdr, buf, WORDS_LEN)) > 0) { /* read server words is ok */
      printf("server read words : %s\n", buf);
      buf[n] = '\0';
      write(fdw, buf, strlen(buf));  
    }
  }
  
  close(fdw);  
  unlink(FIFO_SVR);
  exit(0);
}

客戶端的例子: 

/*
 * Fifo client
 *
 */
#include "all.h"

int
main(void)
{
  int fdr, fdw;
  pid_t pid;  
  char clt_path[PATH_LEN] = {'\0'};
  char buf[MAX_LINE] = {'\0'};
  char buf_path[MAX_LINE] = {'\0'};
  
  snprintf(clt_path, PATH_LEN, FIFO_CLT_FMT, (long)getpid());    
  DBG("clt_path1 = ", clt_path);
  snprintf(buf_path, PATH_LEN, "%s\r\n", clt_path);

  if (mkfifo(clt_path, FILE_MODE) == -1 && errno != EEXIST)  
    perr_exit("mkfifo()");

  /* client open clt_path for read
   * open server for write 
    */
  if ((fdw = open(FIFO_SVR, O_WRONLY)) < 0) 
    perr_exit("open()");
  
  /* write my fifo path to server */  
  if (write(fdw, buf_path, PATH_LEN) != PATH_LEN)    
    perr_exit("write()");
  if (write(fdw, WORDS, WORDS_LEN) < 0)  /* write words to fifo server */
    perr_exit("error");

  if ((fdr = open(clt_path, O_RDONLY)) < 0)  
    perr_exit("open()");
  if (read(fdr, buf, WORDS_LEN) > 0) {   /* read reply from fifo server */
    buf[WORDS_LEN] = '\0';
    printf("server said : %s\n", buf);
  }
  
  close(fdr);
  unlink(clt_path);
  
  exit(0);
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • ubuntn備份方法總結(四種)

    ubuntn備份方法總結(四種)

    本文給大家收藏整理了四種關于ubuntn備份方法,每種方法給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-11-11
  • Linux系統(tǒng)中KafKa安裝和使用方法 java客戶端連接kafka過程

    Linux系統(tǒng)中KafKa安裝和使用方法 java客戶端連接kafka過程

    這篇文章主要介紹了Linux系統(tǒng)中KafKa安裝和使用方法 java客戶端連接kafka過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 使用VMware虛擬機安裝Linux(CentOS7鏡像)

    使用VMware虛擬機安裝Linux(CentOS7鏡像)

    這篇文章介紹了使用VMware虛擬機安裝Linux(CentOS7鏡像)的方法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-12-12
  • CentOS7安裝PHP7 Redis擴展的方法步驟

    CentOS7安裝PHP7 Redis擴展的方法步驟

    這篇文章主要介紹了CentOS7安裝PHP7 Redis擴展的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • Windows10安裝linux子系統(tǒng)的兩種方式(圖文詳解)

    Windows10安裝linux子系統(tǒng)的兩種方式(圖文詳解)

    這篇文章主要介紹了Windows10安裝linux子系統(tǒng)的兩種方式,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • Linux新建虛擬機Ubuntu的圖文教程

    Linux新建虛擬機Ubuntu的圖文教程

    這篇文章主要詳細介紹了Linux新建虛擬機Ubuntu的教程,文章通過圖文結合的方式給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-09-09
  • Linux如何定時執(zhí)行任務教程

    Linux如何定時執(zhí)行任務教程

    Linux crontab是采用定期執(zhí)行程序的命令,當安裝完成操作 系統(tǒng)后,默認便會啟動此任務調度命令,crond命令每分鐘都會定期檢查是否要執(zhí)行任務的工作,如果要執(zhí)行的工作便會自動執(zhí)行該任務。本文主要介紹了定時任務Crontab的使用,需要的可以學習一下
    2023-04-04
  • bt寶塔面板php7.3、php7.4不支持ZipArchive解決方法

    bt寶塔面板php7.3、php7.4不支持ZipArchive解決方法

    這篇文章主要介紹了bt寶塔面板php7.3、php7.4不支持ZipArchive解決方法,需要的朋友可以參考下
    2020-06-06
  • Centos 7.4服務器時間同步配置方法【基于NTP服務】

    Centos 7.4服務器時間同步配置方法【基于NTP服務】

    這篇文章主要介紹了Centos 7.4服務器時間同步配置方法,結合實例形式分析了NTP服務器安裝、啟動、設置時間同步等相關命令及問題解決方法,需要的朋友可以參考下
    2019-03-03
  • Linux的Socket IO模型趣解

    Linux的Socket IO模型趣解

    這篇文章主要通過一個幽默的方式為大家詳細介紹了Linux的Socket IO模型,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11

最新評論

琼海市| 隆子县| 定西市| 房产| 莱西市| 辽中县| 项城市| 车险| 潍坊市| 宜兰市| 祁门县| 日喀则市| 巩义市| 长垣县| 海晏县| 贵德县| 珠海市| 兴文县| 庆城县| 吕梁市| 青田县| 海原县| 桑植县| 突泉县| 于田县| 公安县| 三门县| 石景山区| 堆龙德庆县| 石狮市| 惠水县| 崇礼县| 区。| 通河县| 崇州市| 高雄县| 巫溪县| 静海县| 苏尼特左旗| 隆安县| 新安县|