IPC和管道簡介(轉)
IPC和管道簡介(轉)[@more@]1 Interprocess Communication (IPC)和管道Pipes 在UNIX的核心環境中,要解決的一個首要問題是:如何控制和處理不同程式之間的通訊和資料交換。本章中我們將透過研究一個簡單的例項,看看在同一臺機器的UNIX環境下多個程式是如何執行和被我們控制的(使用fork()方法)。 能夠實現程式間通訊的方法有: · Pipes · Signals · Message Queues · Semaphores · Shared Memory · Sockets 本文先學習如何使用Pipes 方法來實現兩個程式間的通訊,而其它程式間通訊的方法我們將在接下來的文章中詳細討論。 在UNIX環境下可以使用兩種方式開啟一個管道:Formatted Piping方式和Low Level Piping方式。1.1 popen() -- Formatted Piping FILE *popen(char *command, char *type) 描述了開啟一個I/O管道的方法。 其中command引數描述建立管道的程式,type引數描述了管道開啟的型別:"r"表示以讀方式開啟,"w"表示以寫方式開啟。 popen()的返回值是一個指標流或NULL指標(出現錯誤時)。 使用popen()方法開啟的管道,在使用完畢後必須用pclose(FILE *stream)方法關閉。 使用者介面可以透過fprintf()和fscanf()方法來實現和管道的通訊。1.2 pipe() -- Low level Piping int pipe(int fd[2]) 將建立一個管道和兩個檔案描述符:fd[0], fd[1]。 其中fd[0] 檔案描述符將用於讀操作,而fd[1] 檔案描述符將用於寫操作。 pipe()的成功返回值是0,如果建立失敗將返回-1並將失敗原因記錄在errno中。 使用int pipe(int fd[2])建立管道的標準程式設計模式如下: 1) 建立管道; 2) 使用fork( )方法建立兩個(或多個)相關聯的程式; 3) 使用read()和write()方法操作管道; 4) 管道使用完畢後用close(int fd)方法關閉管道。 下一段程式中使用了該種Low Level Piping的方法,實現了父程式對子程式的寫操作: int pdes[2]; pipe(pdes); if ( fork() == 0 ) {/* child */ close(pdes[1]); /* not required */ read( pdes[0]); /* read from parent */ ..... } else { close(pdes[0]); /* not required */ write( pdes[1]); /* write to child */ ..... }1.4 應用例項分析 本節提供了一個完整的管道應用例項,其結構說明如下: 1) 例項含有兩個程式模組plot.c (主程式)和plotter.c; 2) 程式執行在Solaris2.6環境下並必須預先安裝了GNU的免費畫圖軟體gnuplot 在以下目錄:/usr/local/bin/; 3) 程式plot.c呼叫gnuplot; 4) Plot將產生兩個資料流: y = sin(x) y = sin(1/x) 5) 程式將建立兩個管道:每個資料流對應一個管道。 本例項在Solaris2.6的UNIX環境下除錯透過。plot.c程式的原始碼如下:/* plot.c - example of unix pipe. Calls gnuplot graph drawing package to drawgraphs from within a C program. Info is piped to gnuplot *//* Creates 2 pipes one will draw graphs of y=0.5 and y = random 0-1.0 *//* the other graphs of y = sin (1/x) and y = sin x *//* Also user a plotter.c module *//* compile: cc -o plot plot.c plotter.c */#include "externals.h"#include#define DEG_TO_RAD(x) (x*180/M_PI)double drand48();void quit();FILE *fp1, *fp2, *fp3, *fp4, *fopen();main(){ float i;float y1,y2,y3,y4;/* open files which will store plot data */if ( ((fp1 = fopen("plot11.dat","w")) == NULL) ||((fp2 = fopen("plot12.dat","w")) == NULL) ||((fp3 = fopen("plot21.dat","w")) == NULL) ||((fp4 = fopen("plot22.dat","w")) == NULL) ){ printf("Error can't open one or more data files
");exit(1);}signal(SIGINT,quit); /* trap ctrl-c call quit fn */StartPlot();y1 = 0.5;srand48(1); /* set seed */for (i=0;;i+=0.01) /* increment i forever use ctrl-c to quit prog */{ y2 = (float) drand48();if (i == 0.0)y3 = 0.0;elsey3 = sin(DEG_TO_RAD(1.0/i));y4 = sin(DEG_TO_RAD(i));/* load files */fprintf(fp1,"%f %f
",i,y1);fprintf(fp2,"%f %f
",i,y2);fprintf(fp3,"%f %f
",i,y3);fprintf(fp4,"%f %f
",i,y4);/* make sure buffers flushed so that gnuplot *//* reads up to data file */fflush(fp1);fflush(fp2);fflush(fp3);fflush(fp4);/* plot graph */PlotOne();usleep(250); /* sleep for short time */}}void quit(){ printf("
ctrl-c caught:
Shutting down pipes
");StopPlot();printf("closing data files
");fclose(fp1);fclose(fp2);fclose(fp3);fclose(fp4);printf("deleting data files
");RemoveDat();}The plotter.c module is as follows:/* plotter.c module *//* contains routines to plot a data file produced by another program *//* 2d data plotted in this version *//**********************************************************************/#include "externals.h"static FILE *plot1,*plot2,*ashell;static char *startplot1 = "plot [] [0:1.1]'plot11.dat' with lines,'plot12.dat' with lines
";static char *startplot2 = "plot 'plot21.dat' with lines,'plot22.dat' with lines
";static char *replot = "replot
";static char *command1= "/usr/local/bin/gnuplot> dump1";static char *command2= "/usr/local/bin/gnuplot> dump2";static char *deletefiles = "rm plot11.dat plot12.dat plot21.dat plot22.dat";static char *set_term = "set terminal x11
";voidStartPlot(void){ plot1 = popen(command1, "w");fprintf(plot1, "%s", set_term);fflush(plot1);if (plot1 == NULL)exit(2);plot2 = popen(command2, "w");fprintf(plot2, "%s", set_term);fflush(plot2);if (plot2 == NULL)exit(2);}voidRemoveDat(void){ ashell = popen(deletefiles, "w");exit(0);}voidStopPlot(void){ pclose(plot1);pclose(plot2);}voidPlotOne(void){ fprintf(plot1, "%s", startplot1);fflush(plot1);fprintf(plot2, "%s", startplot2);fflush(plot2);}voidRePlot(void){ fprintf(plot1, "%s", replot);fflush(plot1);}The header file externals.h contains the following:/* externals.h */#ifndef EXTERNALS#define EXTERNALS#include#include#include/* prototypes */void StartPlot(void);void RemoveDat(void);void StopPlot(void);void PlotOne(void);void RePlot(void);#endif作者的電子郵件地址是:vong@21cn.com
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-938913/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- IPC(一)---------匿名管道
- android IPC及原理簡介Android
- 介紹 Linux 中的管道和命名管道Linux
- IPC實現機制(一)---pipe(匿名管道)
- 【IPC程式間通訊之二】管道PipeC程式
- Windows管道技術簡述 (轉)Windows
- Linux中重定向和管道介紹Linux
- Android程式間通訊(IPC)機制Binder簡要介紹和學習計劃Android
- Hook簡介 (轉)Hook
- NFS簡介(轉)NFS
- gcc 簡介(轉)GC
- UNIX簡介(轉)
- PGP 簡介(轉)
- Servlet簡介 (轉)Servlet
- CMM簡介 (轉)
- MapX 簡介 (轉)
- xCBL簡介 (轉)
- WBEM簡介 (轉)
- redis的簡單使用和介紹(轉載)Redis
- 簡介DoS和DDoS的攻擊方法(轉)
- 防止別人用ipc$和預設共享入侵(轉)
- 簡易版管道模式模式
- [轉]SSH框架簡介框架
- CVS 簡介(轉)
- 德爾菲法簡介(轉)
- Telnet簡介(轉)
- TurboLinux簡介(轉)Linux
- QFD簡介(轉載)
- C++簡介 (轉)C++
- Bioperl的簡介 (轉)
- ODAC簡介(續) (轉)
- Web Services 簡介 (轉)Web
- crontab命令簡介(轉)
- Linux IPC小結(轉)Linux
- HTTP介紹和HTML簡介HTTPHTML
- dom物件和jQuery物件相互轉換簡單介紹物件jQuery
- Hashtable簡介和使用
- RubyGems簡介和使用