进程间通信--命名管道
幾個術語
- 二義性:當我們往一個管道里面寫端寫數(shù)據(jù)的時候,比如寫一個hello的時候,當我們寫到he的時候,讀端就已經(jīng)開始讀取數(shù)據(jù)了,所以這是不對的,這就是二義性
- 臨界資源:多個流可以訪問的一個共同的存儲資源
- 臨界區(qū):訪問臨界資源的代碼叫做臨界區(qū)
- 互斥:任一時候只能有一個進程利用臨界資源訪問臨界區(qū),并且是以原子性訪問
- 原子性:要么訪問,要么沒有訪問,不存在正在訪問的情況
- 饑餓問題:一個進程因為級別低,在某些場景之下要求訪問某一資源的時候一直訪問不了,這就出現(xiàn)了饑餓問題
- 同步:按照某一順序訪問臨界資源
命名管道
命名管道的概念
匿名管道(pipe)的一個不足之處就是,匿名管道只能用于具有血緣關系的進程之間的通信,但是進程間通信的時候有很多時候都不是具有血緣關系的,這個時候就需要其他的一些通信方式,然后就有了命名管道。 命名管道通過一個路徑將各個進程相連,只要一個進程能夠訪問某一個路徑就能夠訪問這個管道了
命名管道的創(chuàng)建和讀寫
在shell下面我們可以使用mknod和mkfifo來創(chuàng)建管道
這里我們經(jīng)常使用的是mkfifo,所以只是簡單的介紹一個mkfifo,另一個就不做詳細的介紹了
我們在shell下可以使用mkfifo myfifo.pipe來創(chuàng)建一個命名管道,然后在記住他的路徑,在使用的時候,我們可以直接通過open來打開一個管道進行讀寫的 操作
下面的是程序中使用的mkfifo函數(shù),先看接口原型
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename, mode_t mode);
解釋一些返回值和參數(shù),創(chuàng)建成功返回0,失敗返回-1。
參數(shù)中const char *filename,就是一個路徑加上文件名的形式,mode_t mode是我們創(chuàng)建的這個管道的操作權限,我們可以是設置為0666 | S_IFIFO,如下的使用方式,其中的S_IFIFO是一個固定的操作命名管道的一種方式,這里先不用管
我們在函數(shù)中可以按照如下的使用
if(fifo("./pipe",0666 | S_IFIFO) < 0)
{printf("fifo error");return 1;
}
下面我們通過一個簡單的程序實現(xiàn)一個寫端,一個讀端的操作,這個時候我們可以打開兩個終端,分別運行下面的程序,就會實現(xiàn)進程間通信,一個寫,一個讀
寫 端
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>#define _PATH_ "/home/xiaoxu/code/fifo/log.pipe"int main()
{umask(0);if(mkfifo(_PATH_,0666|S_IFIFO) < 0 ){printf("fifo error\n");return 1;}int fd = open(_PATH_,O_WRONLY);if(fd <= 0){printf("open error\n");return 1;}else{char buf[100];memset(buf,'\0',sizeof(buf));while(1){scanf("%s",&buf);int wr = write(fd,buf,sizeof(buf));if(wr <= 0){printf("write error\n");break;}}}close(fd);return 0;
}
讀端
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>#define _PATH_ "/home/xiaoxu/code/fifo/log.pipe"int main()
{int fd = open(_PATH_,O_RDONLY); //只讀方式打開一個管道if(fd < 0) //打開管道失敗{printf("read error\n");return 1;}else //打開管道成功{char buf[100];memset(buf,'\0',sizeof(buf));while(1){int red = read(fd,buf,sizeof(buf)); //把管道里面的內(nèi)容讀取到buf中,所以上面應該加上memset這個函數(shù),對buf進行初始化if(red <= 0) //{printf("read error\n");break;}printf("%s\n",buf);}close(fd);}return 0;
}
總結
以上是生活随笔為你收集整理的进程间通信--命名管道的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 亚比之魂换哪只好
- 下一篇: 求一个香港老电视剧,刑侦类。半夜想不起来