標籤:處理序間通訊 ipc pipe
處理序間通訊-pipe
處理序間通訊
每個進程各自有不同的使用者地址空間,任何一個進程的全域變數在另一個進程中都看不到,所以進程之間要交換資料必須通過核心,在核心中開闢一塊緩衝區,進程1把資料從使用者空間拷到核心緩衝區,進程2再從核心緩衝區把資料讀走,核心提供的這種機制稱為處理序間通訊(IPC,InterProcess Communication)。
pipe
管道(pipe)就是一項基本的處理序間通訊的方法。
#include <unistd.h>int pipe(int pipefd[2]);
使用pipe函數,就可以構建一條通訊管道。
pipefd是傳出參數,表示檔案描述符。pipefd[0]是管道的讀端,pipefd[1]是管道的寫端。
成功,返回0;出錯,返回-1。
管道的本質是環形隊列。
管道的通用使用模式是先pipe。再fork。於是,父子進程都各有了一份管道的讀端和寫端。這表明父子進程本質上都可以讀寫管道,但使用中遵循唯讀唯寫的習慣:父子進程要麼唯讀,要麼唯寫。
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>void sys_err(char *s){perror(s);exit(1);}int main(void){char buf[100];int fd[2];pid_t pid;if (pipe(fd) < 0) sys_err("pipe");//get the size of pipeprintf("pipe size is %ld\n", fpathconf(fd[0], _PC_PIPE_BUF));pid = fork();if (pid < 0) sys_err("fork");else if (0 == pid){/* in child */close(fd[1]); //子進程關閉寫端int n;while (1){n = read(fd[0], buf, 100);write(STDOUT_FILENO, buf, n);}close(fd[0]);}else{/* in parent */close(fd[0]); //父進程關閉讀端int i = 0;while (1){sprintf(buf, "zhangxiang %d\n", i++);write(fd[1], buf, strlen(buf));sleep(1);}close(fd[1]);}return 0;}pipe size is 4096zhangxiang 0zhangxiang 1zhangxiang 2zhangxiang 3zhangxiang 4zhangxiang 5^c
通過fpathconf函數可以擷取管道的大小(單位:位元組)。這個值不是固定的,與系統設定有關。
以上的樣本中父進程關閉讀端,不斷地往管道中寫資料,子進程關閉寫端,不斷地從管道中讀資料。這是典型的父子進程通過管道通訊的方式。
父進程若是想讀,子進程若是想寫,則需另開闢一條管道進行通訊。
CCPP Blog 目錄
著作權聲明:本文為博主原創文章,轉載,請註明出處。
linux C/C++:處理序間通訊-pipe