管道通信机制与消息缓冲机制Word格式文档下载.docx
- 文档编号:21871286
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:10
- 大小:18.28KB
管道通信机制与消息缓冲机制Word格式文档下载.docx
《管道通信机制与消息缓冲机制Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《管道通信机制与消息缓冲机制Word格式文档下载.docx(10页珍藏版)》请在冰豆网上搜索。
-1。
(2)无名管道pipe()的使用
16.1、使用无名管道pipe()进行父子进程之间的通信
源程序代码如下:
charparent[]="
Amessagetopipe'
communication.\n"
;
main()
{
intpid,chan1[2];
charbuf[100];
pipe(chan1);
pid=fork();
if(pid<
0)
printf("
tocreatechilderror\n"
);
exit
(1);
}
if(pid>
close(chan1[0]);
parentprocesssendsamessagetochild.\n"
write(chan1[1],parent,sizeof(parent));
close(chan1[1]);
parentprocesswaitsthechildtoterminate.\n"
wait(0);
parentprocessterminate.\n"
}else{
read(chan1[0],buf,100);
Themessagereadbychildprocessfromparentis:
%s.\n"
buf);
close(0);
childprocessterminate\n"
}
实验运行结果如图所示:
2、以命令行为参数的管道通信
(1)命令格式
stdio.h>
FiLepopen(constcharcmdstring,constchartype);
(2)打开一个以命令行为参数的管道文件,完成进程之间的通信
16.2、以命令行为参数的管道文件的示例
假设有一个可执行程序chcase,从标准输入设备读字符,将小写字母转换成大写字母并进行输出。
主程序使用popen创建管道,实现将某文本文件中的字母转换成大写字母,期中的文本文件名作为参数传进来。
sys/wait.h>
#defineMAXLINE100
intmain(intargc,char*argv[])
charline[MAXLINE];
FILE*fpin,*fpout;
if(argc!
=2){
fprintf(stderr,"
usage:
a.out<
pathname>
\n"
if((fpin=fopen(argv[1],"
r"
))==NULL)
{fprintf(stderr,"
can'
topen%s\n"
argv[1]);
if((fpout=popen("
/root/LiFang/chcase.exe"
"
w"
popenerror\n"
while((fgets(line,MAXLINE,fpin))!
=NULL)
if(fputs(line,fpout)==EOF){
fputserrortopipe.\n"
}
if(ferror(fpin))
fgetserror.\n"
if(pclose(fpout)==-1){
pcloseerror.\n"
exit(0);
实验运行结果如下图所示:
3、有名管道的通信
(1)创建一个有名管道的系统调用mknod()
sys/stat.h>
fcntl.h>
intmknod(constchar*pathname,mode_tmode,dev_tdev);
(2)打开一个有名管道
open(pathname,oflg);
(3)有名管道的使用
16.3、创建有名管道的例子
charstring[]="
thisisaexampletoshowfifocommunication"
main(argc,argv)
intargc;
char*argv[];
{
intfd;
charbuf[256];
inti;
mknod("
fifo"
010777,0);
if(argc==2)
fd=open("
O_WRONLY);
else
O_RDONLY);
for(i=0;
i<
26;
i++)
if(argc==2){
\nIhavewrote:
%s"
string);
write(fd,string,45);
string[0]+=1;
read(fd,buf,256);
\nThecontextbyIhavereadis:
!
%s"
buf[0]='
\0'
close(fd);
试验运行结果如下图所示:
二、消息缓冲机制
1、消息缓冲机制使用的数据结构
(1)消息缓冲区
structmsgbuf{
longmtype;
charmtext[N];
};
(3)消息头结构
structmsg{
structmsg*msgnext;
longmsgtype;
shortmsgts;
shortmsgspot;
2、消息缓冲的系统调用
(1)建立一个消息队列
#include<
sys/ipc.h>
sys/msg.h>
intmsqid=msgget(key_tkey,intmsgflg);
(2)向消息队列发送消息
sys/smg.h>
intmsgsnd(intmsqid,void*msgp,size_tmsgsz,intmsgflg);
(3)接收消息
intmsgrcv(intmsqid,voidmsgp,size_tmsgsz,longmsgtyp,intmsgflg);
(4)取或送消息队列的控制信息
intmsgctl(intmsqid,intcmd,structmsqid_ds*buf);
3、利用消息缓冲机制的通信过程
16.4创建一个私有消息队列,一个进程自己发送消息和接收消息。
源程序代码如下图所示:
16.5创建一个公共消息队列,实现客户进程和服务者进程之间进行通信
客户进程:
#defineREQ1
#defineSVKEY75
structmsgform{
longmtype;
charmtext[256];
main(){
structmsgformmsg;
intmsqid,pid,*pint;
msqid=msgget(SVKEY,0777);
pid=getpid();
pint=(int*)msg.mtext;
*pint=pid;
msg.mtype=REQ;
msgsnd(msqid,&
msg,sizeof(int),0);
msgrcv(msqid,&
msg,256,pid,0);
clientreceivedserver'
sserviceresultisserver'
spid:
%d.\n"
*pint);
服务者进程:
intmsqid;
main(){
inti,pid,*pint;
msqid=msgget(SVKEY,0777|IPC_CREAT);
for(;
;
){
msg,256,REQ,0);
serverisdoingtheserviceforaclient.\n"
pid=*pint;
serverreceiveclient'
sservicerequestisclient'
%d.\n"
pid);
msg.mtype=pid;
*pint=getpid();
四、实验过程与分析
分析:
1、无名管道的通信
父进程先使用pipe(chan1)系统调用打开一个无名管道,之后创建一个子进程。
子进程复制父进程的打开文件表。
为了正确通信,父进程关闭读通道close(chan1[0]),子进程分别关闭写通道close(chan1[1])。
父进程向管道写,子进程从管道读。
完成一次通信后,父进程分别关闭自己的写或者读通道,管道文件消失。
次进程先运行父进程,父进程向无名管道写一条消息,此时父进程等待子进程从管道读取消息,直到子进程结束,最后父进程结束。
2、以命令行为参数的管道通信
本程序先运行chcase.c程序,生成chcase.exe可执行文件,次程序的目的是将小写字母转换成大写字母,主程序先打开文本文件,通过popen创建一个可写管道,将命令行的chcase的输入与管道的输出连接起来,然后向管道输入数据,那么,命令行就可以通过管道连接收文本文件的数据了,可实现将文本文件中的小写字母转换成大写字母。
进程间使用有名管道实现通信时,必须有三次同步。
第一次是打开同步。
当一个进程以读方式打开有名管道时,若已有写者打开过,则唤醒写着后继续前进,否则,睡眠等待写者。
当一个进程以写方式打开有名管道时,若以有读者打开过,则唤醒读者继续前进,否则等到读者。
第二次是读写同步。
其同步方式与pipe相同。
允许写者超前读者1024个字符。
当一次写超过1024时,超前的字符要写入时,超前的字符要写入时,则写者必须等待,读者从有名管道时,若没有可读则等待。
若有数据可读,读完后要检测有无写者等待。
若有唤醒写者。
而且要求读写两方面随时检查通信的另一方是否还存在,一旦有一方不存在,应立即终止通信过程。
第三次是关闭同步。
当一个写进程关闭有名管道时,若发现有进程睡眠等待从管道读,则唤醒它,被唤醒进程立即从读调用返回。
当一个读进程有名管道时,若发现有进程睡眠等待向管道写,则唤醒它,并向他发一个指示错误条件的信号后返回,最后一个关闭有名管道的进程,释放该管道占用的全部盘块及相应主存i节点。
有名管道打开后,就可以使用读写命令进行读写,读写完成后就立即关闭。
有名管道文件关闭后,文件本身并没有消失。
有名管道的读写和关闭动作与普通文件完全相同。
4、利用消息缓冲机制的通信过程
该进程创建了一个公共消息队列,实现客户进程和服务进程之间进行通信。
客户进程向服务进程发送消息,请求服务,服务进程接收消息,完成客户的服务请求后,再将服务结果消息发送给客户。
具体实现描述为:
服务进程用关键字SVKEY和标志IPC_CRAT调用msgget()建立一个消息队列,得到其队列标识符msqid之后,用msqid调用msgrcv()接收类型为REQ的消息。
客户进程用关键字SVKEY调用msgget()得到消息队列标识符msqid,之后用msqid调用msgsnd()将自己的pid发送到消息队列(SVKEY)中,表示其所请求的服务。
然后调用msgrcv()等待服务结果消息的到来。
服务者进程接收到请求服务的消息后进行服务工作,完成服务后向客户进程发回一条消息,消息类型为客户的标识pid,消息正文是服务进程自己的标识pid。
五、实验总结
通过本次实验,我掌握了UNIX和LINUX进程通信系统的调用的功能。
理解了UNIX和Linux操作系统进程通信的系统调用。
最终学会如何利用系统调用命令进行进程通信编程,通过学习,提高对进程之间可通过系统的编程能力,最后在老师的指导下顺利地完成了本次的实验。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 管道 通信 机制 消息 缓冲