1,進程間通信 (IPC ) Inter-Process Communication
比較好理解概念的就是進程間通信就是在不同進程之間傳播或交換信息。
2,linux下IPC機制的分類:管道、信號、共享內存、消息隊列、信號量、套接字
3,這篇主要說說管道:本質是文件,其他理論什么的網上已經有一大堆了,我就只寫一點用法吧。
3.1 特點
1)管道是最古老的IPC,但目前很少使用
2)以文件做交互的媒介,管道分為有名管道和無名管道
3)歷史上的管道通常是指半雙工管道
3.2 管道:有兩種形式,命令行和非命令行
(1)命令行:
mkfifo testfifo
echo "testfifo" >fifo
cat fifo
(2)非命令行:這里又分有名管道和無名管道
編程模型:進程A創建管道(mkfifo) -> 進程A寫打開管道(open) -> 進程B讀打開管道(open) -> 進程A開始往管道里寫數據(write) ->
進程B從管道中讀數據(read) -> 進程A關閉管道(close) -> 進程B關閉管道(close) -> 刪除管道(unlink)
有名管道(實例):
進程A:
#include<sys/stat.h> #include<fcntl.h> #include<stdio.h> #define PIPENAME "pipetest" int main() { // 創建管道 if(mkfifo(PIPENAME, 0666) < 0) { perror("mkfifo"); return -1; } // 寫打開管道 int fd = open(PIPENAME, O_WRONLY); if(-1 == fd) { perror("open"); return -1; } unlink(PIPENAME); int i = 0; for(i = 0; i < 10; i++) { write(fd, &i, sizeof(i)); printf("%d\n", i); sleep(1); // 這個是以秒為單位掛起 } // 關閉管道 close(fd); return 0; }
進程B:
#include<sys/stat.h> #include<fcntl.h> #include<stdio.h> #define PIPENAME "pipetest" int main() { // 讀打開管道 int fd = open(PIPENAME, O_RDONLY); if(-1 == fd) { perror("open"); return -1; } int num = 0; int i = 0; for(i = 0; i < 10; i++) { read(fd, &num, sizeof(int)); printf("%d\n", num); fflush(stdout); // 強制刷新輸出緩沖區 } printf("\n"); close(fd); return 0; }
運行效果如下:
開另外一個終端,運行讀進程
無名管道:適用於父子進程之間的通信
int pipe(int pipefd[2]):該函數在內核中創建管道文件,通過輸出參數pipefd返回兩個文件描述符,其中pipefd[0]用於讀,pipefd[1]用於寫。
注意:
寫數據的進程關閉讀端pipefd[0]
讀數據的進程關閉寫端pipefd[1]
實例:
#include<stdio.h> #include<unistd.h> #include<fcntl.h> #include<stdlib.h> int main() { int fd[2]; // 用來保存文件描述符 pipe(fd); pid_t pid = fork();// 創建進程 if(pid > 0) { // 父進程寫管道,需要關閉讀端 close(fd[0]); int i = 0; for(i=10; i<20; i++) { write(fd[1], &i, sizeof(int)); sleep(1); } close(fd[1]);// 關閉寫端 exit(0); } // 子進程讀管道 close(fd[1]); // 先關閉寫端 int x; int i = 0; for(; i<10; i++) { read(fd[0], &x, sizeof(int)); printf("%d ", x); setbuf(stdout, NULL); } close(fd[0]); printf("\n"); return 0; }
運行效果如下: