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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

linux进程间通信:命名管道FIFO

發布時間:2023/11/27 生活经验 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux进程间通信:命名管道FIFO 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

        • FIFO 通信特點
        • 系統調用接口
        • 應用
          • 擁有親緣關系之間的進程通信
          • 非親緣關系進程之間的通信
        • 總結

FIFO 通信特點

  • FIFO文件有文件名
    • 可以像普通文件一樣存儲在文件系統之中
    • 可以像普通文件一樣使用open/write讀寫
    • 和pipe文件一樣屬于流式文件,不能使用lseek系統調用重定位文件偏移地址
  • 具有寫入原子性,支持多個進程同時對FIFO進行寫操作,如日志系統/var/log
  • First in First out,先入先出。最先被寫入的數據最先被讀出來
    • 默認阻塞讀,阻塞寫的特性。可以在open的時候進行設置
    • 如果一個進程打開fifo的一端時,令一端沒有打開,該進程會被阻塞。

fifo與pipe最大的區別就是pipe只能用于親緣進程之間的通信(fork方式創建的父子進程),但是fifo可以支持任意兩個進程之間的通信,并包括擁有親緣關系的進程

系統調用接口

  • shell命令:mkfifo pathname,可以通過man mkfifo查看命令用法
  • 函數接口:int mkfifo(const char *pathname,mode_t mode)
  • 函數功能:創建fifo的有名管道
  • 函數參數:
    - pathname FIFO管道文件名
    - mode 讀寫權限

應用

擁有親緣關系之間的進程通信

通信過程類似于pipe的fd[0]讀出,fd[1]寫入


#include <sys/types.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>#define FIFO "testfifo"
int main()
{int a=mkfifo(FIFO,0644);if (0 != a)printf("mkfifo failed %d\n",a);int ret,fifo_fd;ret = fork();if (ret == -1) {perror("fork");_exit(-1);}//子進程負責寫入管道else if (ret == 0) {fifo_fd = open("testfifo",O_RDWR);char buf[100];memset(buf,0,100);printf("child process(%d) input msg:",getpid());//scanf("%s",buf);fgets(buf,10,stdin);int write_len = write(fifo_fd,buf,strlen(buf));printf("%d bytes has been sent\n",write_len);_exit(1);}//父進程進行從管道進行讀取else {sleep(5);fifo_fd = open("testfifo",O_RDWR);char buf[100];memset(buf,0,100);printf("father process befor read\n");int read_len = read(fifo_fd,buf,100);if (read_len == -1)printf("read error %d\n",read_len);printf("father process(%d) read message from fifo :%s\n",getpid(),buf);_exit(1);}return 0;
}
非親緣關系進程之間的通信

寫端:


#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define FIFO_NAME "testfifo"int main(int argc, char* argv[])
{int fd;char buf[100];mkfifo(FIFO_NAME, S_IFIFO|0666);//循環向testinfo中寫入數據while (1){printf("please input the string : \n");fd = open(FIFO_NAME, O_WRONLY);fgets(buf,100,stdin);write(fd, buf, strlen(buf)+1);close(fd);}unlink(FIFO_NAME); //刪除命名管道文件sleep(1);return 0;
}

讀端:

#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define FIFO_NAME "testfifo"
#define BUF_SIZE 1024int main(int argc, char* argv[])
{int fd;char buf[BUF_SIZE];//循環從testinfo中讀取數據while (1) {fd = open(FIFO_NAME, O_RDONLY);//read系統調用會從打開的文件當前文件偏移地址開始讀,即上次寫入的數據read(fd, buf, BUF_SIZE);printf("%s\n", buf);close(fd);}return 0;
}

總結

為什么無名管道只能用于父子進程之間的通信呢?無名管道是一個文件,但是只能存在與內存之中,且該文件的讀寫方式是固定的,我們只能從一端寫入,一端讀出。使用無名管道通信,他得文件句柄需要在同一個進程內共享。即在同一個進程內只有fork的方式,能夠將當前進程所有文件描述符以及進程狀態信息拷貝給另一個進程;只有在這樣的進程關系之下,無名管道的數據傳輸才能實現一端寫入,一端讀出。

命名管道fifo可以像普通文件一樣存在與操作系統磁盤之中,同樣支持read/write的數據讀寫,因此它能夠被多個進程共同訪問。雖然fifo相比于pipe使用范圍擴大了,但是總體的阻塞式通信依然存在。

pipe的內核實現fs/pipe.cpipe_readpipe_write函數處理過程中都是通過加鎖mutex來實現,并沒有相關的異步操作,而fifo的fifo_open函數同樣是阻塞式處理函數體。

總結

以上是生活随笔為你收集整理的linux进程间通信:命名管道FIFO的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。