進程間通信之:管道
8.2.5FIFO
1.有名管道說明
前面介紹的管道是無名管道,它只能用于具有親緣關系的進程之間,這就大大地限制了管道的使用。有名管道的出現突破了這種限制,它可以使互不相關的兩個進程實現彼此通信。該管道可以通過路徑名來指出,并且在文件系統中是可見的。在建立了管道之后,兩個進程就可以把它當作普通文件一樣進行讀寫操作,使用非常方便。不過值得注意的是,FIFO是嚴格地遵循先進先出規則的,對管道及FIFO的讀總是從開始處返回數據,對它們的寫則把數據添加到末尾,它們不支持如lseek()等文件定位操作。
有名管道的創建可以使用函數mkfifo(),該函數類似文件中的open()操作,可以指定管道的路徑和打開的模式。
小知識 | 用戶還可以在命令行使用“mknod管道名p”來創建有名管道。 |
在創建管道成功之后,就可以使用open()、read()和write()這些函數了。與普通文件的開發設置一樣,對于為讀而打開的管道可在open()中設置O_RDONLY,對于為寫而打開的管道可在open()中設置O_WRONLY,在這里與普通文件不同的是阻塞問題。由于普通文件的讀寫時不會出現阻塞問題,而在管道的讀寫中卻有阻塞的可能,這里的非阻塞標志可以在open()函數中設定為O_NONBLOCK。下面分別對阻塞打開和非阻塞打開的讀寫進行討論。
(1)對于讀進程。
n 若該管道是阻塞打開,且當前FIFO內沒有數據,則對讀進程而言將一直阻塞到有數據寫入。
n 若該管道是非阻塞打開,則不論FIFO內是否有數據,讀進程都會立即執行讀操作。即如果FIFO內沒有數據,則讀函數將立刻返回0。
(2)對于寫進程。
n 若該管道是阻塞打開,則寫操作將一直阻塞到數據可以被寫入。
n 若該管道是非阻塞打開而不能寫入全部數據,則讀操作進行部分寫入或者調用失敗。
2.mkfifo()函數格式
表8.4列出了mkfifo()函數的語法要點。
表8.4 mkfifo()函數語法要點
所需頭文件 | #includesys/types.h> | |
函數原型 | intmkfifo(constchar*filename,mode_tmode) | |
函數傳入值 | filename:要創建的管道 | |
函數傳入值 | mode: | O_RDONLY:讀管道 |
O_WRONLY:寫管道 | ||
O_RDWR:讀寫管道 | ||
O_NONBLOCK:非阻塞 | ||
函數傳入值 | mode: | O_CREAT:如果該文件不存在,那么就創建一個新的文件,并用第三個參數為其設置權限 |
O_EXCL:如果使用O_CREAT時文件存在,那么可返回錯誤消息。這一參數可測試文件是否存在 | ||
函數返回值 | 成功:0 | |
出錯:-1 | ||
表8.5再對FIFO相關的出錯信息做一歸納,以方便用戶查錯。
表8.5 FIFO相關的出錯信息
EACCESS | 參數filename所指定的目錄路徑無可執行的權限 |
EEXIST | 參數filename所指定的文件已存在 |
ENAMETOOLONG | 參數filename的路徑名稱太長 |
ENOENT | 參數filename包含的目錄不存在 |
ENOSPC | 文件系統的剩余空間不足 |
ENOTDIR | 參數filename路徑中的目錄存在但卻非真正的目錄 |
EROFS | 參數filename指定的文件存在于只讀文件系統內 |
linux相關文章:linux教程
數字通信相關文章:數字通信原理
通信相關文章:通信原理












評論