[15]APUE:pipe / FIFO

管道 pipeshell

1、概述數組

  • 管道(pipe / FIFO)是一種文件,屬於 pipefs 文件系統類型,可使用 read、write、close 等系統調用進行操做
  • 其本質是內核維護了一塊緩衝區與管道相關聯,對管道的任何操做,都將被內核轉換成讀寫對應的內存緩衝區
  • 只有當全部的寫入端描述符均已關閉,且管道中的數據都被讀出後,對讀端描述符調用 read 纔會返回 0 (EOF)
  • 若全部讀端已關閉,此時往管道的寫操做會失敗,調用進程會收到 SIGPIPE 信號,errno 被設置爲 EPIPE
  • 當全部的讀端與寫端均關閉後,管理才能被銷燬
  • 一般只保留一對一的讀寫端口,無用的端口需及時關閉

2、函數函數

[a] pipespa

#include <unistd.h>
int pipe(int pipefd[2]) //成功返回 0,出錯返回 -1 
  • 將整型數組 pipefd 的兩個元素初始化爲一對文件描述符,分別用於從管道中讀數據(pipefd[0])、寫數據(pipefd[1])
  • 因爲 fork 以後子進程繼承父進程的文件描述符,pipe 一般用於父子進程通訊
  • 同一會話中的進程可經過複製(dup2)文件描述符的方式實現管道通訊,如 shell 的 ‘|’ 功能

[b] popen / pclose操作系統

#include <stdio.h>
FILE *popen(const char *cmd, const char *type) //成功返回 FILE 流指針,出錯返回 NULL
int pclose(FILE *stream) //成功返回 0,出錯返回 -1 
  • popen 用於經過 shell 執行外部程序 cmd
    • 當 type 設置爲 「r」 時,經過 fgets、fgetc 等函數可獲取 cmd 執行結果(標準輸出)
    • 當 type 爲 「w」 時,寫經過 fputs 等函數爲 cmd 標準輸入
  • 與 system 函數原理相似,但 system 在返回以前,調用程序將一直阻塞;而 popen 不一樣,在調用 popen 以後到 pclose 返回以前這段時間,調用進程與被執行的 shell 子進程是並行的,若在此期間,調用程序又 fork 了子進程且安裝了 SIGCHLD 信號的處理函數,可能致使 shell 子進程返回的 SIGCHLD 信號被捕獲,從而使 pclose 沒法等待 cmd 進程的退出而失敗

命名管道 FIFO指針

1、概要code

  • FIFO 是在 fifo 核心代碼之上構建的外殼,經過文件系統中的文件直接引用,可用於同一操做系統內任意兩個進程的通訊
  • FIFO 經過設置不一樣的 open 權限標誌位區分輸入輸出端,讀端一般設置 O_RDONLY,寫端一般設置 O_WRONLY
  • 管道傳輸的內容一般爲非結構化的字節流,當多個客戶端同時鏈接服務端 FIFO 時,爲準確區分不一樣客體的內容,一般客戶端發送的字節流前 N 個字節固定用於指定當次傳輸的數據長度

2、函數blog

[a] mkfifo繼承

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *path, mode_t mode) //成功返回 0,出錯返回 -1 
  • fcntl 函數設置的 O_NONBLOCK 標誌位會對 FIFO 的行爲產行影響
    • 當寫端未就緒時,讀操做將也會當即以成功狀態返回,errno 設置爲 EAGAIN
    • 當讀端未就緒時,寫操做將當即以出錯狀態返回,並設置 errno 爲 ENXIO
  • 識別 FIFO 文件類型:用 stat 或 fstat 函數將文件屬性寫入 buf 結構體,S_ISFIFO(buf->st_mode) 的返回真(1)即爲 FIFO
相關文章
相關標籤/搜索