程式間通訊系列--管道
程式間通訊系列--管道
管道可以說是最古老的IPC形式,所謂管道,是指程式間建立的一條通訊的通道,從本質上看,管道是UNIX檔案概念的推廣管道通訊的介質是檔案,先看一下管道的特點:
1.管道的特點:
(1)管道是半雙工的,資料只能向一個方向流動;需要雙方通訊時,需要建立起兩個管道;
(2)無名管道只能用於父子程式或者兄弟程式之間(具有親緣關係的程式);後來發展了FIFO(也稱有名管道)
(3)單獨構成一種獨立的檔案系統:管道對於管道兩端的程式而言,就是一個檔案,但它不是普通的檔案,它不屬於某種檔案系統,而是自立門戶,單獨構成一種檔案系統,並且只存在與記憶體中。
(4)資料的讀出和寫入:一個程式向管道中寫的內容被管道另一端的程式讀出。寫入的內容每次都新增在管道緩衝區的末尾,並且每次都是從緩衝區的頭部讀出資料。
2.無名管道API及操作:
標頭檔案:#include
資料成員:int pipe_fd[2];
管道建立:int pipe(int fd[2])
該函式建立的管道的兩端處於一個程式中間,在實際應用中沒有太大意義,因此,一個程式在由pipe()建立管道後,一般再fork一個子程式,然後透過管道實現父子程式間的通訊(因此也不難推出,只要兩個程式中存在親緣關係,這裡的親緣關係指的是具有共同的祖先,都可以採用管道方式來進行通訊)。
管道讀寫:
管道兩端可分別用描述字fd[0]以及fd[1]來描述,管道讀端:fd[0],管道寫端:fd[1];
讀管道規則:
關閉管道的寫端:close (fd[WRITE]);
讀出:read(fd[READ],string,strlen(string));
讀出後關閉管道的讀端:close(fd[REAd]);
寫管道規則:
關閉管道的讀端:close(fd[REAd]);
寫入:write(fd[WRITE],string,strlen(string));
寫入後關閉管道的寫端:close (fd[WRITE]);
下面練習一個簡單的單管道通訊:
父程式寫資料,子程式負責讀出資料
view plaincopy to clipboardprint?
/**************
* readtest.c *
**************/
#include
#include
#include
#define READ 0
#define WRITE 1
main()
{
int pipe_fd[2];
pid_t pid;
char r_buf[100];
char w_buf[32];
char* p_wbuf;
int r_num;
int cmd;
memset(r_buf,0,sizeof(r_buf));
memset(w_buf,0,sizeof(r_buf));
p_wbuf=w_buf;
if(pipe(pipe_fd)<0)
{
printf("pipe create error ");
return -1;
}
if((pid=fork())==0) //子程式讀
{
close(pipe_fd[WRITE]);
sleep(3); //確保父程式關閉寫端
r_num=read(pipe_fd[READ],r_buf,100);
printf( "read num is %d the data read from the pipe is %s n",r_num,r_buf);
close(pipe_fd[READ]);
exit();
}
else if(pid>0) //父程式寫
{
close(pipe_fd[READ]);
strcpy(w_buf,"hello world!n");
if(write(pipe_fd[WRITE],w_buf,strlen(w_buf))==-1)
printf("parent write overn ");
close(pipe_fd[WRITE]);
printf("parent close fd[WRITE] over n");
sleep(10);
}
}
/**************
* readtest.c *
**************/
#include
#include
#include
#define READ 0
#define WRITE 1
main()
{
int pipe_fd[2];
pid_t pid;
char r_buf[100];
char w_buf[32];
char* p_wbuf;
int r_num;
int cmd;
memset(r_buf,0,sizeof(r_buf));
memset(w_buf,0,sizeof(r_buf));
p_wbuf=w_buf;
if(pipe(pipe_fd)<0)
{
printf("pipe create error ");
return -1;
}
if((pid=fork())==0) //子程式讀
{
close(pipe_fd[WRITE]);
sleep(3); //確保父程式關閉寫端
r_num=read(pipe_fd[READ],r_buf,100);
printf( "read num is %d the data read from the pipe is %s n",r_num,r_buf);
close(pipe_fd[READ]);
exit();
}
else if(pid>0) //父程式寫
{
close(pipe_fd[READ]);
strcpy(w_buf,"hello world!n");
if(write(pipe_fd[WRITE],w_buf,strlen(w_buf))==-1)
printf("parent write overn ");
close(pipe_fd[WRITE]);
printf("parent close fd[WRITE] over n");
sleep(10);
}
}
編譯執行,看到預期結果
3.利用兩個管道進行雙向通訊
(1)建立兩個管道:管道1(父->子),管道2(子->父)
(2)fork()產生子程式
(3)父程式:close(fd1[READ]); close(fd2[WRITE]);
(4)子程式:close(fd1[WRITE]); close(fd2[READ]);
下面做一個練習,是利用雙向通訊實現父子程式協作把整數x從1加到10
view plaincopy to clipboardprint?
#include
#include
#include
#include
#include
#define MAXLINE 1024
#define READ 0
#define WRITE 1
main(void)
{
int x;
pid_t pid;
int pipe1[2],pipe2[2];
/*初始化管道*/
pipe(pipe1);
pipe(pipe2);
pid = fork();
if(pid < 0)
{
printf("create process error!n");
exit(1);
}
if(pid == 0) //子程式
{
close(pipe1[WRITE]);
close(pipe2[READ]);
do
{
read(pipe1[READ],&x,sizeof(int));
printf("child %d read: %dn",getpid(),x++);
write(pipe2[WRITE],&x,sizeof(int));
}while(x<=9);
//讀寫完成後,關閉管道
close(pipe1[READ]);
close(pipe2[WRITE]);
exit(0);
}
else if(pid > 0) //父程式
{
close(pipe2[WRITE]);
close(pipe1[READ]);
x = 1;
//每次迴圈向管道1 的1 端寫入變數X 的值,並從
//管道2 的0 端讀一整數寫入X 再對X 加1,直到X 大於10
do{
write(pipe1[WRITE],&x,sizeof(int));
read(pipe2[READ],&x,sizeof(int));
printf("parent %d read: %dn",getpid(),x++);
}while(x<=9);
//讀寫完成後,關閉管道
close(pipe1[WRITE]);
close(pipe2[READ]);
waitpid(pid,NULL,0);
exit(0);
}
}
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/benny_cen/archive/2009/03/10/3976546.aspx
[@more@]來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24790158/viewspace-1041140/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 20.2、python程式間通訊——佇列和管道Python佇列
- 程式間通訊(一)管道
- Linux 下的程式間通訊:使用管道和訊息佇列Linux佇列
- Linux 的程式間通訊:管道Linux
- linux 程式間通訊之管道Linux
- linux程式間通訊--管道(PIPE & FIFO)Linux
- Linux程式間通訊②:有名管道FIFOLinux
- 溫故之.NET程式間通訊——管道
- 【IPC程式間通訊之二】管道PipeC程式
- 3|程式間通訊--有名管道學習筆記筆記
- linux程式間通訊-----管道總結例項Linux
- 多程式通訊系列問題
- LLinux系統程式設計(10)——程式間通訊之管道Linux程式設計
- 管道流間的通訊
- 程序間通訊(1)-管道
- Delphi 簡單命名管道在兩個程式間通訊
- Linux系統程式設計之程式間通訊方式:管道(二)Linux程式設計
- Linux系統程式設計之程式間通訊方式:管道(一)Linux程式設計
- Linux系統程式設計(11)——程式間通訊之有名管道Linux程式設計
- 在父子程式間用管道傳遞檔案描述符
- 有名管道程式碼
- Linux系統程式設計之程式間通訊方式:命名管道(二)Linux程式設計
- Linux系統程式設計之程式間通訊方式:命名管道(一)Linux程式設計
- Linux程式執行緒學習筆記:程式間通訊 之 管道Linux執行緒筆記
- C#使用匿名管道在本地程式之間進行通訊C#
- 程式間通訊--訊息佇列佇列
- java 管道流程式碼示例Java
- linux系統程式設計之管道(一):匿名管道(pipe)Linux程式設計
- linux系統程式設計之管道(三):命令管道(FIFO)Linux程式設計
- C# 管道式程式設計C#程式設計
- 使用DOS管道的程式碼片段
- 數字通訊系統
- linux系統程式設計之管道(二):管道讀寫規則Linux程式設計
- C#使用命名管道通過網路在程式之間進行通訊C#
- 利用管道Pipelines做程序間的通訊
- PHP多程式程式設計(2):管道通訊PHP程式設計
- MongoDB 聚合嵌入的陣列(扁平化資料+管道)MongoDB陣列
- 系統程式設計——管道通訊程式設計