还剩10页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
Uexx进程通信命名管道FIFO小结LL〃x下进程之间通信可以用命名管道F/F完成命名管道是一种特殊类型的文件,因为LM〃x中所有事物都是文件,它在文件系统中以文件名的形式存在在程序中,我们可以使用两个不同的函数调用来建立管道^includesgs/stat・h〉it^itw\kfifoco八stckar为67c八4Hac》i^odejtMode;Mk八odcco八优char兴八〃M也ModestMode|SJFIFOO;下面先来创建一个管道[cpp]Hewp⑶八copg#Mclud〈stdio.h〉#iccbdcstdlib.h#McLdesgs/tgpcs.k#Mcln4csys/stat.hiint{iiatres=Mkfifo〃/tMp/Mg_fifo〃0777;q.ifres==69{
11.priiatfuFIFOcreated/^1}:
22.
13.cxitEXIT_SUCCESS;X
4.编译这个程序gcc一fifo^.cfifo运行这个程序:$./fif工X
8.{X
9.stderrSorrycreateclientfifofailure!/八〃;20ex/*EX/匚FAILURE;2L.serveirjifojd=op/SER\/ER_FIFO_NAME一WRONLY;.ifscn/cir_fifo_f4==-1{
6.fpiri八tRstdewSorirgopenserverfifofaibr!/八〃;6xitEXIT^FAlLURE;273C.sp-i八tfMsg.dataHdlofrom%dJMsg.cient_picl;pirMtf〃%dsc八t%si^sg.client_pidw^sg.data;wHtcserver_fifo_fdMsg』sizefmsg;cliei^t_fifo_fd二openctie^t_fifo^aCLRDONLY;ifd也八t_fifo_fd==T{fpYintfstAc”」So“gclientfifoopc八faibre!/八〃;
38.cxitEXIT_FAILURE;res=ireadcieAt_fifo_fdn/\sgs/2eofH/1sg;ifresO{p/Mtf〃匕ccci\/cd:%s//-xsg/ntn;}45coseclieht_fifo_fd;c/oscservcr__frfo_fd;〃八/讥kc〃c八t_fifo_八amc;
49.
50.exitEX【T_SUCCESS;编译程序gcc一serverservercgcc一clientclii^t.c测试这个程序,我们需要一个服务器进程和多个客户进程为了让多个客户进程在同一时间启动,我们使用了$M\命令[root@localk\o^tckapcir]#./server[
2.6]SI71[root@localkostchape丫12]#forii八22345;do./clientdone
[27]5172
[22]Si73
[29]5274
[50]5275
[31]SI76[root@localko£tchaper12]#5172sentHellofrom5272wccivcd:HELLFROM5272SX73SC八土Hellof/OhASX73received:HELLFROMS173SI74sentHellof/OMSI74received:HELLFROM52745275sentHellofnw5275received:HELLFROM52755276sentHellohow\5276r6cived:HELLOFROM5工76分析这个例子,服务器以只读模式创建它的曰F并阻塞,直到第一个客户以写方式打开同一现个F/F来建立连接为止此时,服务器进程解除阻塞并执行s/eep语句,这使得来自客户的数据排除等候在实际应用程序中,应该把s/ccp语句删除,这里面只是为了演示当有多个客户请求同时到达时,程序的正确操作方法与此同时,在客户端打开服务器F/F后,它创建自己唯一的一个命名管道以读取服务器返回的数据完成这些工作后,客户发送数据给服务器(如果管道满或服务器仍处于休眠就阻塞),并阻塞于对自己F/F的七4d调用上,等待服务器响应接收到来自客户的数据后,服务器处于它,然后以写的方式打开客户管道并将处理后的数据返回,这将解除客户端的阻塞状态,客户程序就可以从自己的管道里面读取服务器返回的数据了整个处理过程不断重复,直到最后一个客户关闭服务器管道为止,这将使服务器的七“d调用失败(返回),因为已经没有进程以写方式打开服务器管道了如果这是一个真正的服务器进程的话,它还需要继续等待其他客户的请求,我们就需要对它进行修改,有两种方法2对它自己的服务器管道打开一个文件描述符,这样%4d调用将阻塞而不是返回2当%“d调用返回时,关闭并重新打开服务器管道,使服务器进程阻塞在八调用处以等待客户的到来,就像它最初启动时那样用k命令查看所创建的管道Is-IF^rwxr-xr-x2rootrootO05-OS20:2/tMp/Mg_fifo注意k命令的输出结果中的第一个字符为p表示这是一个管道最后的|符号是由k命令的-F选项添加的,它也表示是这是一个管道虽然,我们所设置的文件创建模式为“0777但它被用户掩码um^sk设置22给改变了这与普通文件创建是一样的,所以文件的最终模式为755打开F/F一个主要的限制是,程序不能是_RDWR模式打开曰F文件进行读写操作,这样做的后果未明确定义这个限制是有道理的,因为我们使用F/F只是为了单身传递数据,所以没有必要使用一RDWR模式如果一个管道以读/写方式打开曰F,进程就会从这个管道读回它自己的输出如果确实需要在程序之间双向传递数据,最好使用一对F/F,一个方向使用一个当一个进程被阻塞时,它并不消耗CPU资源,这种进程的同步方式对CPU而言是非常有效率的有关Lmux下命名管道FIFO的读写规则可以参见之前所写的一篇文章L讥“X命名管道F/F的读写规则
一、实验使用FIFO实现进程间通信两个独立的程序生产者程序,它在需要时创建管道,然后尽可能快地向管道中写入数据消费者程序,它从F/F中读取数据并丢弃它们生产者程序fif2c[cpp]copg〈stdio.h〉#includestdlib.h〈stiri八g.h〉#Mcfefcntl.h^ii^cludeo.#McL4c〈sgs/tgpes.h〉sgs/stat.kq.#dcfi八FIFO_NAME/tmp/Li八iax/913UFFER_SIZEPIPE__13UF工工.#defMeTEN_ME1024*2024*2Mt25intpipe_fd;X
6.Mtres;intoen_HAode=CLWRONLY;26Mtbytes=9;ck\airbuffer[13UFFE^SIZE+1];if®ccessF/FO_NAMEjF_OK二二Tres=MkfifoFlFCLNAME0777;ifres/=O{
2.
7.fpri八tfstdcH〃CobdWi^otcreatefifo%s/八〃/FIFO_NAME;2g.cxitEX1匚FAILURE;
2630.3X.pirMtfPirocess%dope八MgFIFOO_WRONLY/八〃getpid;pipe_fd=opccFIFO_NAMEopcn_Mode;piri八tfProcess%dresu/t%d/「gctpictpipc_f4;ifpipc_fd!=T{wk/7cbytesTEN_MEGres=wiritcpipc_fclbufferBJFFER_S/ZE;ifres==-1{error八pipe/八〃;cxitEXIT_FAILURE;bytes十二res;1cosepipc_fd;else{cxitEXIT_FAILURE;pH八tfProcess%dfMisk/八〃getpid;exitEXIT_SUCCESS;}消费者程序行foBc[epp]Hewplaihcopg#Scndcstdio.W#McLdc〈stcUib.h〉#Mdnde〈stiri八g.h〉#Mclndcfc八k#ScIa4c#Scbdesgs/tgpcs.k#McL4csys/stat.kq.#dcfMcFIFO_NAME/tmp/LMux/mg_fif3#行八c13UFFER_SIZEPIPEJ3UF
21.
22.X
4.
25.
17.
28.
19.
221.
22.
2324.
25.
2.
627.
22.
2730.
31.
32.
33.
34.3S.
36.
37.
38.
39.44L
42.Mt{Mtpipc_fd;intres;iv\topcAjAAodc=CLRDONLY;ckarbfeir[BUFFER_SIZE+1];Mtbgtes=MCMSctbhffd/OLsizeofbiAffer;pn八tf〃FVocess%dopei八ingFIFOO_RDONLY/八〃gctpid;pipe_fd=opcMFlFO_NAMEom_Modc;pirMtfProcess%dresult%d/getpidpipc_fd;ifpipc_fd/=-1do{res=readpipe_fdbufferBUFFER_S/ZE;bgtes十=res;}wk阳VcsO;coscpipc_fd;ekecxitEXIT_FAILURE;pnhtf〃Proccss%dfi八ished%dbytesrc〃d/八〃gctpidbytes;cxitEX工SUCCESS;编译这两个程序:gcc一fifo2fifo
2.cgcc一fifo3fifo
3.c运行这两个程序[rootf^localkostckapcr工2j#./fifo2今后台执行,写数据[2J22工Process23222opc八MgFIFOO_WRONLY[root@locafhostchapcS2]#time./肝32读数据Process24255opci八MgFIFOCLRDONLYProcess23222result3Process24255result3Process23222finishProcess24255finished1048576bytesread
[2]-Do八/fifo2realOm
9.224suserOw\OOOOssgsOw\O.^7^s以上两个程序均是使用阻塞模式曰FLM,x会安排好这两个进程之间的调试,使它们在可以运行的时候运行,在不能运行的时候阻塞因此,写进程将在管道满时阻塞,读进程将在管道空时阻塞虚拟机上,力mc命令显示,读进程只运行了2秒的时间,却读取了工0M字节的数据这说明管道在程序之间传递数据是非常有效的
二、实验使用FIFO的客户/服务器应用程序利用F/F实现一个客户/服务器的应用程序,服务器进程接受请求,对它们进程处理,最后把结果数据返回给发送请求的客户方首先建立一个头文件c能八七人,它定义了客户和服务器程序都要用到的数据结构,并包含了必要的头文件[epp]HewplaMcopg#kcfe〈stdio.h〉stdib.h〉认g.k#Mcia4c〈fcctLh〉d.#McLdcsgs/tgpcs.h#inc【ndcsgs/stat.h〉q.#AcfMcSERVER_F【FO_NAME/±Mp/Li八认x/chapcir L2/scn/CY_fif
20.#dcfi八cCLIENT_FIFO_NAME/tMp/LMAX/chapciri2/cicAt_%d_fif
11.#dcfMeBUFFER_SIZEPIPE_8UF#dcfincMESSACE_SIZE2#def证cNAME_SIZE256typedefstructMessage.{.pidjtcliei^t_pid;chardata[MESSAGE_SIZE+X]j2Message;接下来是服务器程序scrvccc在这一部分,是以只读阻塞模式打开服务器管道,用于接收客户发送过来的数据,这些数据采用messogc结构体封装[epp]viewplaincopg#Mclndcclic八t.hint用4八01ietscrvCK_fifo_fd;intcic八Mtres;q.ck\arcIient_fifo」\amc[NAME_SIZE];
311.Messageksg;X
3.来p;ifMkfifoSERVER_FIFO_NAME0777==一2{
17.fprihSongcreateserverfifofaiLsc!/八〃;
28.exi^EXHLFA/LURE;
19.
222.serveirjifojd=opSERVER_FIFO_NAMECLRDONLY;
22.ifscn/er_fifo_f4二二-
22.3{fpiri八tfstdc也Song〉serverfifoopenfaibir!/八〃;.cxitEXIT_FAILURE;}scep5;3t
9.wk/7cres=ircadscirver_fifo_fdhsgsizeoRmsgO3X.{p=i^sgdata;wk〃e关p共p=土叩per关p;++;spirMtfcie八CLIENT_FIFO_NAMEi^sg.cliei^t_pid\c〃c八=叩©八91八七_徘_八2O_WRONLY;4X.ifcliei^t_fifojd==TfpHiA±fstdc〃Sogclientfifoope八fn/M%!/八〃;cxitEXIT_FALURE;wiritecfo_fdms夕sizcofmsg;4g.closcc/也八t_fifo_fd;.c/oscscrvcr_fifo_fd;A八iMcSERVER_FIFO_NAME;6xitEXIT__SUCCESS;客户端程序c/也八七以这个程序用于向服务器发送消息,并接收来自服务器的回复[cpp]HewplaMcopg#include〃cient・h/kt八0{Mtscn/er_fifo_fd;o.intdie八ictres;q.2charcifo_naMc[NAME_SIZE];
22.
22.messagen/\sg;
13.
24.MSg.cicct_pid=getpid;IS.spkMtfcic八t_fifo_namcCUENT_FIFCLNAMEMSg.dicnt^id;X
6.
17.ifMkfifocic八t_fifo」1aMe0777==-1。
个人认证
优秀文档
获得点赞 0