管道檔案操作

2022-06-21 08:48:08 字數 2615 閱讀 8796

管道檔案

#include
int pipe(int fildes[2]);
呼叫成功後,可以訪問兩個檔案描述符,fildes[0]是用來讀的檔案描述符,而fildes[1]是用來寫的檔案描述符。

pipe僅允許單向通訊,fildes[0]只用來讀,fildes[1]只用來寫。若要雙向通訊,必須建立兩組管道。

在實際使用中,通過建立乙個子程序,然後乙個程序寫,乙個程序讀來使用。

必須在fork()前呼叫pipe(),否則子程序不會繼承檔案描述符。兩個程序不共享祖先程序,就不能使用pipe。但是可以使用命名管道。

當管道進行寫入操作的時候,如果寫入的資料小於128k則是原子的,如果大於128k位元組,緩衝區的資料將被連續地寫入

管道,直到全部資料寫完為止,如果沒有程序讀取資料,則將一直阻塞。

雖然管道是一種特殊的檔案,它的讀寫操作和普通檔案的讀寫操作完全一樣,但管道不是乙個真實存在的檔案,它只在核心中儲存,而不存在於檔案系統中。

int dup2(int oldfd, int newfd);

dup2將永oldfd檔案描述符來代替newfd檔案描述符,同時關閉newfd檔案描述符。也就是說,所有指向newfd的操作都轉到oldfd上面。

命名管道又稱先入先出佇列,是一種特殊的管道,存在於檔案系統中。其顯著特點:

》命名管道可以用於任何兩個程序間的通訊,並不限制於兩個程序同源。

》命名管道作為一種特殊的檔案存放於檔案系統中,而不是像管道一樣存放於核心中。當程序對命名管道使用結束後,命名管道依然存在於檔案系統中,除非對其進行刪除,否則該命名管道不會消失。

和管道一樣,命名管道也僅允許單向通訊,若要雙向通訊,必須建立兩組命名管道。

#include

#include

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

mode與建立普通檔案的create()的mode相似,成功返回0,失敗返回-1。

int mknod(char *pathname, mode_t mode, dev_t dev);

mknod不是乙個專門用於建立命名管道的函式,引數pathname/mode和mkfifo相同,dev取0。成功0,失敗-1。

shell命令建立命名管道:

mkfifo fifo_test

mknod fifo_test p

可以像普通檔案一樣,open/read/write/close fifo。

注:使用命名管道時,需要在兩個進行通訊的程序中分別開啟命名管道。因此,當乙個程序讀開啟(或寫開啟)乙個fifo而沒有其他程序寫開啟(或讀開啟)此fifo時,該程序就會阻塞,直到另乙個程序寫開啟(或讀開啟)此fifo。

若要刪除乙個命名管道,使用unlink。

4. 使用注意

使用命名管道與管道的注意問題一樣:

》向未開啟或已經關閉的管道進行寫操作,將產生sigpipe訊號,write函式將errno設定為出錯值。

》當乙個程序從命名管道中讀取資料時,如果命名管道中的全部資料讀完了,read()認為讀到了檔案末尾,返回值為0。但有可能資料的寫入並沒有結束,寫入命名管道的程序還有資料要傳輸。因此要分清楚是資料傳輸結束還是暫時無資料讀取,如果是後者,則讀取資料的程序應等待。

》系統定義的常量pipe_buf規定了命名管道緩衝的大小,當寫入資料超過規定大小後,將會使資料發生交錯。ulimit -a顯示pipe_buf值(ubuntu16.04)為512bytes * 8 = 4096 bytes。

posix.1規定當寫入管道的長度小於pipe_buf位元組時必須是原子的:即寫入資料作為連續序列寫入管道。 超過pipe_buf位元組的寫入可能是非原子的:核心可能會將資料與其他程序寫入的資料交錯。

posix.1要求pipe_buf至少為512位元組。(在linux上,pipe_buf為4096位元組)。在實踐中取決於檔案描述符是否為非阻塞(o_nonblock),管道中是否有多個寫入器,以及n要寫入的位元組數:

n <= pipe_buf, o_nonblock無效:原子的寫入n個位元組。如果管道當前的剩餘空間不足以立即寫入n個位元組,就阻塞直到有足夠的空間。

n <= pipe_buf, o_nonblock有效:寫入具有原子性,如果有足夠的空間寫入n個位元組,write立即成功返回。否則乙個都不寫入,返回錯誤,並設定errno為eagain。

n > pipe_buf, o_nonblock無效:非原子寫。可能會和其它的寫程序交替寫。write阻塞直到將n個位元組寫入管道。

n > pipe_buf, o_nonblock有效:如果管道滿,則write失敗,返回錯誤,並將errno設定為 eagin。如果不滿,則返回寫入的位元組數為1~n,即部分寫入,寫入時可能有其他程序穿插寫入。

結論: 1、當要寫入的資料量不大於pipe_buf時,linux將保證寫入的原子性。 2、當要寫入的資料量大於pipe_buf時,linux將不再保證寫入的原子性。

管道高階操作

coding utf 8 define your item pipelines here don t forget to add your pipeline to the item pipelines setting see import pymysql class qiubaipipeline o...

Linux管道操作

理解linux作業系統中管道的原理和使用方法。學會編寫簡單的無名管道程式。include int pipe int filedes 2 返回值 成功,返回0,否則返回 1。引數陣列包含pipe使用的兩個檔案的描述符。fd 0 讀管道,fd 1 寫管道。首先呼叫pipe函式,產生乙個無名管道。使用fo...

scrapy檔案管道

安裝scrapy pip install scrapy 新建專案 python36 e www scrapy startproject filedownload new scrapy project filedownload using template directory c users brad...