無(wú)錫兼職做網(wǎng)站電商培訓(xùn)內(nèi)容
目錄
一、匿名管道
1.什么是管道?什么是匿名管道?
2.怎么創(chuàng)建匿名管道(函數(shù))
3.匿名管道的4種情況
4.匿名管道有5種特性
?5.怎么使用匿名管道?匿名管道有什么用?(例子)
二、命名管道
1.什么是命名管道?
2.怎么創(chuàng)建命名管道(函數(shù))?
3.命名管道的打開(kāi)規(guī)則
4.怎么使用命名管道?命名管道有什么用?(例子)
三、匿名管道和命名管道的區(qū)別?
一、匿名管道
1.什么是管道?什么是匿名管道?
我們把從一個(gè)進(jìn)程連接到另一個(gè)進(jìn)程的一個(gè)數(shù)據(jù)流稱為一個(gè)“管道”。而匿名管道顧名思義,就是一種沒(méi)有名字的“管道”。
2.怎么創(chuàng)建匿名管道(函數(shù))
#include <unistd.h>
功能:創(chuàng)建一無(wú)名管道
原型
int pipe(int fd[2]);
參數(shù)
fd:文件描述符數(shù)組,其中fd[0]表示讀端, fd[1]表示寫(xiě)端記憶方法:0像一張嘴,所以是讀端,1像一支筆,所以是寫(xiě)端
返回值:成功返回0,失敗返回錯(cuò)誤代碼
3.匿名管道的4種情況
1.正常情況,如果管道沒(méi)有數(shù)據(jù)了,讀端必須等待,直到有數(shù)據(jù)為止(寫(xiě)端寫(xiě)入數(shù)據(jù)了)
2.正常情況,如果管道被寫(xiě)滿了,寫(xiě)端必須等待,直到有空間為正(讀端讀走數(shù)據(jù))
3.寫(xiě)端關(guān)閉,讀端一直讀取,讀端會(huì)讀到read返回值為0,表示讀到文件結(jié)尾
4.讀端關(guān)閉,寫(xiě)端一直寫(xiě)入,OS會(huì)直接殺掉寫(xiě)端進(jìn)程,通過(guò)向目標(biāo)進(jìn)程發(fā)送SIGPIPE(13)信號(hào),終止目標(biāo)進(jìn)程
b.管道的5種特性
1.匿名管道,可以允許具有血緣關(guān)系的進(jìn)程之間進(jìn)行進(jìn)程間通信,常用與父子,僅限于此
2.匿名管道,默認(rèn)給讀寫(xiě)端要提供同步機(jī)制 ---了解現(xiàn)象就行
3. 面向字節(jié)流的---了解現(xiàn)象就行
4.管道的生命周期是隨進(jìn)程的
5.管道是單向通信的,半雙工通信的一種特殊情況
4.匿名管道有5種特性
1.匿名管道,可以允許具有血緣關(guān)系的進(jìn)程之間進(jìn)行進(jìn)程間通信,常用與父子,僅限于此
2.匿名管道,默認(rèn)給讀寫(xiě)端要提供同步機(jī)制
3. 面向字節(jié)流的
4.管道的生命周期是隨進(jìn)程的
5.管道是單向通信的,半雙工通信的一種特殊情況
?5.怎么使用匿名管道?匿名管道有什么用?(例子)
例子:
先創(chuàng)建管道, 進(jìn)而創(chuàng)建子進(jìn)程, 父子進(jìn)程使用管道進(jìn)行通信
父進(jìn)程向管道當(dāng)中寫(xiě)“i am father”,?
子進(jìn)程從管道當(dāng)中讀出內(nèi)容, 并且打印到標(biāo)準(zhǔn)輸出(屏幕)
#include <unistd.h>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{int fd[2];//打開(kāi)匿名管道if(pipe(fd) == -1){cout << "open pipe fail" << endl;exit(1);}pid_t id = fork();if(id == 0)//child{char message[30];read(fd[0], message, sizeof(message));cout << message << endl;}//fatherchar s[] = "i am father";write(fd[1], s, sizeof(s));return 0;
}
運(yùn)行后:
二、命名管道
1.什么是命名管道?
匿名管道應(yīng)用的一個(gè)限制就是只能在具有共同祖先(具有親緣關(guān)系)的進(jìn)程間通信
如果我們想在不相關(guān)的進(jìn)程之間交換數(shù)據(jù),可以使用FIFO文件來(lái)做這項(xiàng)工作,它經(jīng)常被稱為命名管道。命名管道是一種特殊類(lèi)型的文件。
2.怎么創(chuàng)建命名管道(函數(shù))?
命名管道可以從命令行上創(chuàng)建,命令行方法是使用下面這個(gè)命令
mkfifo filename
命名管道也可以從程序里創(chuàng)建,相關(guān)函數(shù)有?
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename,mode_t mode);
filename:命名管道的名字
mode:權(quán)限值
返回值:成功返回0,失敗返回-1
3.命名管道的打開(kāi)規(guī)則
如果當(dāng)前打開(kāi)操作是為讀而打開(kāi)FIFO時(shí)
- O_NONBLOCK (disable):阻塞直到有相應(yīng)進(jìn)程為寫(xiě)而打開(kāi)該FIFO
- O_NONBLOCK (enable):立刻返回成功
如果當(dāng)前打開(kāi)操作是為寫(xiě)而打開(kāi)FIFO時(shí)
- O_NONBLOCK (disable):阻塞直到有相應(yīng)進(jìn)程為讀而打開(kāi)該FIFO
- O_NONBLOCK (enable):立刻返回失敗,錯(cuò)誤碼為ENXIO
4.怎么使用命名管道?命名管道有什么用?(例子)
創(chuàng)建出來(lái)的命名管道可以供兩個(gè)進(jìn)程通信
進(jìn)程A 向管道當(dāng)中寫(xiě) “i am process A”
進(jìn)程B 從管道當(dāng)中讀 并且打印到標(biāo)準(zhǔn)輸出
processA.cc
#include "fifo.h"
using namespace std;
bool MakeFifo()
{int n = mkfifo(FIFONAME, 0644);if(n < 0){cout << "mkfifo fail" << endl;return false;}return true;
}int main()
{//創(chuàng)建命名管道if(!MakeFifo()){cerr << "mkfifo fail" << endl;return 1;}//打開(kāi)fifo文件寫(xiě)int wfd = open(FIFONAME, O_WRONLY);if(wfd < 0){cerr << "open fifo fail" << endl;return 2;}cout << "Process A is sending a message to process B" << endl;char message[] = "i am process A";write(wfd, message, sizeof(message));return 0;
}
processB.cc
#include "fifo.h"
using namespace std;int main()
{//打開(kāi)fifo文件寫(xiě)int rfd = open(FIFONAME, O_RDONLY);if(rfd < 0){cerr << "open fifo fail" << endl;return 2;}cout << "receives messages from process A: ";char message[30];read(rfd, message, sizeof(message));cout << message << endl;return 0;
}
fifo.h
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
#include <cassert>
#include <fcntl.h>
#include <unistd.h>#define FIFONAME "fifo"
現(xiàn)象:
1.
?2.
?3.
三、匿名管道和命名管道的區(qū)別?
- 匿名管道由pipe函數(shù)創(chuàng)建并打開(kāi)。
- 命名管道由mkfifo函數(shù)創(chuàng)建,打開(kāi)用open
- FIFO(命名管道)與pipe(匿名管道)之間唯一的區(qū)別在它們創(chuàng)建與打開(kāi)的方式不同,一但這些工作完成之后,它們具有相同的語(yǔ)義