管道通信 管道是單向的、先進先出的,由隊列來實現,它把一個進程的輸出和另一個進程的輸入連接在一起 一個進程(寫進程)在管道的尾部寫入數據,另一個進程(讀進程)從管道的頭部讀出數據 管道包括無名管道和有名管道。前者用於父進程和子進程間的通信,後者可用於運行於同一系統的任意兩個進程間的通信。 無名管道 ...
管道通信
管道是單向的、先進先出的,由隊列來實現,它把一個進程的輸出和另一個進程的輸入連接在一起
一個進程(寫進程)在管道的尾部寫入數據,另一個進程(讀進程)從管道的頭部讀出數據
管道包括無名管道和有名管道。前者用於父進程和子進程間的通信,後者可用於運行於同一系統的任意兩個進程間的通信。
無名管道
無名管道由pipe()函數創建
int pipe(int fd[2]);//創建管道,為系統調用:unistd.h
創建成功返回0,失敗返回-1
創建兩個文件描述符:fd[0]用於讀管道,fd[1]用於寫管道
註意:
管道是創建在記憶體中的,進程結束,空間釋放,管道就不存在了
管道中的東西,讀完了就刪除了
如果管道沒有東西可讀,就會讀堵塞
關閉管道,close關閉兩個文件描述符
必須在系統調用fork()前調用pipe(),否則子進程將不會繼承文件描述符(子父各創建了一個管道)
無名管道源代碼
#include <stdio.h> #include<malloc.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int main() { int fd[2]; int fd1; int ret; int i; char a[100]; char b[10] = "123456"; ret = pipe(fd);//管道創建必須在fork()函數之前 if (ret < 0) { printf("創建管道失敗\n"); } else { printf("創建管道成功\n"); } fd1 = fork(); if (fd1 == 0)//子進程 { printf("正在讀取\n"); i = read(fd[0], a, sizeof(a)); printf("已接受%s\n", a); close(fd[0]); } if (fd1 > 0)//父進程 { write(fd[1], b, sizeof(b)); printf("已發送123456\n"); close(fd[1]); } return 0; }
有名管道
1、創建這個文件節點,不可以通過open函數,open函數只能創建普通文件,不能創建特殊文件(管道-mkdifo,套接字-socket,字元設備文件-mknod,塊設備文件-mknod,符號鏈接文件-ln-s,目錄文件 mkdir)
2、管道文件只有inode號,不占磁碟塊空間,和套接字、字元設備文件、塊設備文件一樣。普通文件和符號鏈接文件及目錄文件,不僅有inode號,還占磁碟塊空間
3、mkfifo 用來創建管道文件的節點,沒有在內核中創建管道
只有通過open函數打開這個文件時才會在內核空間創建管道
mkfifo
函數形式 :int mkfifo(const char *filename,mode_t mode);
功能:創建管道文件
參數:管道文件文件名,許可權,創建的文件許可權仍然和umask有有關係
返回值:創建成功返回0,創建失敗返回-1
代碼如下,創建3個.c文件
//創建管道節點 1.c #include <stdio.h> #include<malloc.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int main() { int fd; fd = mkfifo("./write_mkfifo",0777); if (fd < 0) { printf("創建管道節點失敗"); return -1; } else printf("創建管道節點成功"); }
//創建一個進程寫管道 write.c #include <stdio.h> #include<malloc.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int main() { int fd; char a[10]="123456"; fd = open("./write_mkfifo", O_WRONLY); if (fd < 0) { printf("打開管道失敗\n"); } else { printf("打開管道成功\n"); } write(fd,a,sizeof(a)); printf("已發送數據到管道\n"); }
//創建一個進程讀管道 read.c #include <stdio.h> #include<malloc.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int main() { int fd; char b[10]; fd = open("./write_mkfifo", O_RDONLY); if (fd < 0) { printf("打開管道失敗\n"); } else { printf("打開管道成功\n"); } read(fd,b,sizeof(b)); printf("接收數據成功:%s\n",b); close(fd); }
結果如下