日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

linux进程通信:pipe实现进程同步

發(fā)布時(shí)間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)
  • 管道的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)閉
    zhang@ubuntu:/proc/15521$ ls /proc/15691/fd/
    0  1  2  3
    
    子進(jìn)程有如下文件描述符打開(kāi),因?yàn)樽舆M(jìn)程的寫(xiě)文件描述符關(guān)閉,所以4的描述符還存在
    zhanghuigui@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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。