linux进程通信:pipe实现进程同步
生活随笔
收集整理的這篇文章主要介紹了
linux进程通信:pipe实现进程同步
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- 通過(guò)管道同步進(jìn)程
- 實(shí)現(xiàn)代碼
- 管道緩沖區(qū)
- 設(shè)置緩沖區(qū)大小
- 總結(jié) :pipe的特點(diǎn)
通過(guò)管道同步進(jìn)程
- 管道自帶同步互斥機(jī)制:
- 管道的內(nèi)核實(shí)現(xiàn):
fs/pipe.c,主要通過(guò)內(nèi)核的鎖以及等待隊(duì)列等機(jī)制實(shí)現(xiàn)
- 管道的內(nèi)核實(shí)現(xiàn):
- 管道的write操作會(huì)阻塞進(jìn)程
- 當(dāng)內(nèi)存緩沖區(qū)已滿(mǎn)或被讀進(jìn)程鎖定,會(huì)阻塞write操作
- 當(dāng)所有數(shù)據(jù)被寫(xiě)入管道時(shí)write操作才會(huì)結(jié)束
- 管道的read操作會(huì)阻塞進(jìn)程
- 當(dāng)讀進(jìn)程被阻塞時(shí)會(huì)形成等待隊(duì)列,并讓等待隊(duì)列進(jìn)入休眠
- 當(dāng)所有子進(jìn)程關(guān)閉來(lái)管道的寫(xiě)入端的操作時(shí)會(huì)停止阻塞
- 父進(jìn)程的寫(xiě)入端操作關(guān)閉時(shí),父進(jìn)程的讀操作會(huì)停止阻塞
- 當(dāng)所有當(dāng)寫(xiě)端操作符都被關(guān)閉,且管道中當(dāng)數(shù)據(jù)都被讀出,對(duì)讀端描述符調(diào)用read函數(shù)才會(huì)返回結(jié)束
- 當(dāng)所有當(dāng)讀取端和寫(xiě)入端都關(guān)閉后,管道才能被銷(xiāo)毀
實(shí)現(xiàn)代碼
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>#define handle_error(msg)\
{perror(msg);exit(-1);}int main()
{int pipe_fd[2];int buf;printf("parent process(%d) run ...\n",getpid());if (pipe(pipe_fd) == -1)handle_error("pipe");for (int i = 0; i < 4; ++i) {int f;f = fork();if (f == -1)handle_error("fork");if(f == 0){//這里子進(jìn)程先休眠,然后離開(kāi)之前關(guān)閉所有的讀管道if (close(pipe_fd[0]) == -1)_exit(-1);sleep(i * i);printf("child process(%d) closing pipe\n",getpid());if (close (pipe_fd[1]) == -1)_exit(-1);_exit(0);}}//在調(diào)用read系統(tǒng)調(diào)用之前一定要先關(guān)閉進(jìn)程內(nèi)所有的寫(xiě)管道,否則讀會(huì)一直阻塞if (close(pipe_fd[1]) == -1)_exit(-1);// read系統(tǒng)調(diào)用正常讀取文件會(huì)返回大于0都文件字節(jié)數(shù)。//但是當(dāng)其讀到EOF會(huì)返回0,標(biāo)示讀到結(jié)束標(biāo)記//如果返回負(fù)數(shù),則標(biāo)示讀取錯(cuò)誤if (read(pipe_fd[0] ,&buf,1) != 0) perror("parent read can't get EOF");printf("parent process(%d) exited \n",getpid());return 0;
}
輸出如下:
parent process(15454) run ...
child process(15455) closing pipe
child process(15456) closing pipe
child process(15457) closing pipe
child process(15458) closing pipe
parent process(15454) exited
管道緩沖區(qū)
- 管道對(duì)應(yīng)緩沖區(qū)大小
PIPE_BUF的容量是有限制的,默認(rèn)64K- 在不同的os下的
PIPE_BUF大小設(shè)置不同:在limits.h頭文件中定義 - 當(dāng)寫(xiě)入管道當(dāng)數(shù)據(jù)超過(guò)
PIPE_BUF的時(shí)候內(nèi)核會(huì)分割不同的幾塊進(jìn)行傳輸 - 管道傳輸容量的緩沖區(qū)的容量上限設(shè)置不能超過(guò)
1M - 查看打開(kāi)的管道文件:
ls /proc/$pid/fd
可以在如上代碼中的子進(jìn)程處理代碼中的close(pipe_fd[1])之前加入阻塞while(1);
可以看到父進(jìn)程有如下文件描述符打開(kāi),因?yàn)樽枞淖舆M(jìn)程中寫(xiě)文件描述符未關(guān)閉,所以父進(jìn)程的讀文件描述符未關(guān)閉
子進(jìn)程有如下文件描述符打開(kāi),因?yàn)樽舆M(jìn)程的寫(xiě)文件描述符關(guān)閉,所以4的描述符還存在zhang@ubuntu:/proc/15521$ ls /proc/15691/fd/ 0 1 2 3zhanghuigui@ubuntu:/proc/15521$ ls /proc/15692/fd/ 0 1 2 4
設(shè)置緩沖區(qū)大小
- 特權(quán)用戶(hù):可以修改緩沖上限
- 設(shè)置緩沖區(qū)大小:
fcntl(fd,F_SETPIPE_SZ,size)
總結(jié) :pipe的特點(diǎn)
- 無(wú)名管道是字節(jié)流
- 可通過(guò)文件I/O接口讀寫(xiě),但是無(wú)法
lseek修改文件指針的偏移地址 - 單向阻塞通信:一端用于寫(xiě)入,一端用于讀出。實(shí)現(xiàn)雙向通信需要兩個(gè)管道
- 通信簡(jiǎn)單,性能單一,只能在親緣進(jìn)程間通信
總結(jié)
以上是生活随笔為你收集整理的linux进程通信:pipe实现进程同步的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 好听的个性签名女生
- 下一篇: linux 系统调用 open函数使用