主要用于沒有血緣關(guān)系的進程間通信具篇。
特點:
1纬霞、半雙工,數(shù)據(jù)在同一時刻只能在一個方向上流動驱显。
2诗芜、寫入FIFO中的數(shù)據(jù)遵循先入先出的規(guī)則。
3埃疫、FIFO所傳送的數(shù)據(jù)是無格式的伏恐,這要求FIFO的讀出方與寫入方必須事先約定好數(shù)據(jù)的格式,如多少字節(jié)算一個消息等栓霜。
4翠桦、FIFO在文件系統(tǒng)中作為一個特殊的文件而存在,但FIFO中的內(nèi)容卻存放在內(nèi)存中胳蛮。
5销凑、管道在內(nèi)存中對應(yīng)一個緩沖區(qū)。不同的系統(tǒng)其大小不一定相同仅炊。
6斗幼、從FIFO讀數(shù)據(jù)是一次性操作,數(shù)據(jù)一旦被讀抚垄,它就從FIFO中被拋棄蜕窿,釋放空間以便寫更多的數(shù)據(jù)。
7呆馁、當使用FIFO的進程退出后桐经,F(xiàn)IFO文件將繼續(xù)保存在文件系統(tǒng)中以便以后使用。
8浙滤、FIFO有名字阴挣,不相關(guān)的進程可以通過打開命名管道進行通信
2、有名管道的API
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
功能:
? ??創(chuàng)建有名管道FIFO文件的創(chuàng)建
參數(shù):
????pathname:FIFO的路徑名+文件名瓷叫。
????mode:mode_t類型的權(quán)限描述符屯吊。
返回值:
????成功:返回 0
????失敗:如果文件已經(jīng)存在,則會出錯且返回-1
示例代碼
#include<stdio.h>
#include<sys/types.h>?
#include<sys/stat.h>?
#include<fcntl.h>?
#include<string.h>?
#include<unistd.h>?
int main(int argc,char const *argv[])
{?
????????//創(chuàng)建有名管道(保存兩個進程 識別相同目錄)
????????mkfifo("my_fifo", 0666);#ifdef WRITE
????????int fd = open("my_fifo", O_WRONLY);
#endif
#ifdef READ
? ??????int fd = open("my_fifo", O_RDONLY);
#endif
?????????if (fd < 0)
? ? ? ? {
?????????????????perror("open");
?????????????????return 0;
? ? ? ? ?}
#ifdef WRITE?
? ? ? ? //循環(huán)寫入數(shù)據(jù)
? ? ? ? while(1){
????????????????char buf[128] = "";
????????????????printf("請輸入需要發(fā)送的數(shù)據(jù):");
? ? ? ? ? ? ? ? fgets(buf, sizeof(buf), stdin);
????????????????buf[strlen(buf) ‐ 1] = 0;?
? ? ? ? ? ? ? ?//發(fā)送數(shù)據(jù)?
????????????? write(fd, buf, strlen(buf));?
????????????? //退出循環(huán)
????????????? if (strcmp(buf, "bye") == 0)
????????????????????????break;?
? ? ? ? }
#endif#ifdef READ?
//循環(huán)的讀取數(shù)據(jù)?
????????? while (1)? ?
? ? ? ? ?{?
? ? ? ? ? ? ? ? //接收數(shù)據(jù)
? ? ? ? ? ? ? ? char buf[128] = "";?
? ? ? ? ? ? ? ? read(fd, buf, sizeof(buf));
? ? ? ? ? ? ? ? printf("收到數(shù)據(jù)位:%s\n", buf);?
? ? ? ? ? ? ? ? //退出循環(huán)?
? ? ? ? ? ? ? ?if (strcmp(buf, "bye") == 0)?
????????????????????? break;?
? ? ? ? ?}?
#endif?
?????close(fd);?
?????return 0;?
}gcc a.c -o a -D?READ
有名管道讀寫的特點:
道管開打式方塞阻
1摹菠、open以只讀方式打開FIFO時盒卸,要阻塞到某個進程為寫而打開此FIFO
2、open以只寫方式打開FIFO時次氨,要阻塞到某個進程為讀而打開此FIFO蔽介。
3、open以只讀煮寡、只寫方式打開FIFO時會阻塞虹蓄,調(diào)用read函數(shù)從FIFO里讀數(shù)據(jù)時read也會阻塞。
4幸撕、通信過程中若寫進程先退出了薇组,則調(diào)用read函數(shù)從FIFO里讀數(shù)據(jù)時不阻塞;若寫進程又重新運行,則調(diào)用read函數(shù)從FIFO里讀數(shù)據(jù)時又恢復阻塞坐儿。
5律胀、通信過程中,讀進程退出后貌矿,寫進程向命名管道內(nèi)寫數(shù)據(jù)時炭菌,寫進程也會(收到SIGPIPE信號)退出。
6逛漫、調(diào)用write函數(shù)向FIFO里寫數(shù)據(jù)黑低,當緩沖區(qū)已滿時write也會阻塞。
以非阻塞方式打開管道:
1酌毡、先以只讀方式打開:如果沒有進程已經(jīng)為寫而打開一個FIFO, 只讀open成功克握,并且open不阻塞。
2阔馋、先以只寫方式打開:如果沒有進程已經(jīng)為讀而打開一個FIFO玛荞,只寫open將出錯返回-1。
3呕寝、read勋眯、write讀寫命名管道中讀數(shù)據(jù)時不阻塞。
4下梢、通信過程中客蹋,讀進程退出后,寫進程向命名管道內(nèi)寫數(shù)據(jù)時孽江,寫進程也會(收到SIGPIPE信號)退出讶坯。
注意: open函數(shù)以可讀可寫方式打開FIFO文件時的特點:
????1、open不阻塞岗屏。
????2辆琅、調(diào)用read函數(shù)從FIFO里讀數(shù)據(jù)時read會阻塞漱办。
????3、調(diào)用write函數(shù)向FIFO里寫數(shù)據(jù)婉烟,當緩沖區(qū)已滿時write也會阻塞