分享
 
 
 

IPC和管道简介

王朝other·作者佚名  2008-05-18
窄屏简体版  字體: |||超大  

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 draw

graphs 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\n");

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;

else

y3 = sin(DEG_TO_RAD(1.0/i));

y4 = sin(DEG_TO_RAD(i));

/* load files */

fprintf(fp1,"%f %f\n",i,y1);

fprintf(fp2,"%f %f\n",i,y2);

fprintf(fp3,"%f %f\n",i,y3);

fprintf(fp4,"%f %f\n",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("\nctrl-c caught:\n Shutting down pipes\n");

StopPlot();

printf("closing data files\n");

fclose(fp1);

fclose(fp2);

fclose(fp3);

fclose(fp4);

printf("deleting data files\n");

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\n";

static char *startplot2 = "plot 'plot21.dat' with lines,

'plot22.dat' with lines\n";

static char *replot = "replot\n";

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\n";

void

StartPlot(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);

}

void

RemoveDat(void)

{ ashell = popen(deletefiles, "w");

exit(0);

}

void

StopPlot(void)

{ pclose(plot1);

pclose(plot2);

}

void

PlotOne(void)

{ fprintf(plot1, "%s", startplot1);

fflush(plot1);

fprintf(plot2, "%s", startplot2);

fflush(plot2);

}

void

RePlot(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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有