嵌入式Linux多進程通訊試驗報告_第1頁
嵌入式Linux多進程通訊試驗報告_第2頁
嵌入式Linux多進程通訊試驗報告_第3頁
嵌入式Linux多進程通訊試驗報告_第4頁
嵌入式Linux多進程通訊試驗報告_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

頓字沒大考遴NINGBOUNIVERSITY實驗報告實驗題目嵌入式Linux多進程通訊實驗姓名:學號:課程名稱:所在學院:專業(yè)班級:任課教師:實驗項目名稱嵌入式Linux多進程通訊實驗一、實驗目的與要求:1、熟悉UNIX/LINUX支持的無名管道通信方式。2、熟悉UNIX/LINUX支持的有名管道通信方式。3、熟悉LINUX系統(tǒng)中進程之間信號通信的基本原理。4、熟悉UNIX/LINUX支持的共享內存通信方式。5、熟悉UNIX/LINUX支持的消息隊列通信方式。二、實驗設備:華清遠見開發(fā)環(huán)境,PC機三、實驗方法(原理,流程圖)Linux下的進程通信手段基本上是從Unix平臺上的進程通信手段繼承而來的。而對Unix發(fā)展做出重大貢獻的兩大主力AT&T的貝爾實驗室及BSD(加州大學伯克利分校的伯克利軟件發(fā)布中心)在進程間的通信方面的側重點有所不同。前者是對Unix早期的進程間通信手段進行了系統(tǒng)的改進和擴充,形成了“systemVIPC”,其通信進程主要局限在單個計算機內;后者則跳過了該限制,形成了基于套接口(socket)的進程間通信機制。而Linux則把兩者的優(yōu)勢都繼承了下來,如圖1所示。Unix進程間通信(IPC)方式包括管道、FIFO以及信號。SystemV進程間通信(IPC)包括SystemV消息隊列、SystemV信號量以及SystemV共享內存區(qū)。Posix進程間通信(IPC)包括Posix消息隊列、Posix信號量以及Posix共享內存區(qū)?,F(xiàn)在在Linux中使用較多的進程間通信方式主要有以下幾種。圖1進程間通信發(fā)展歷程(1)管道(Pipe)及有名管道(namedpipe):管道可用于具有親緣關系進程間的通信,有名管道,除具有管道所具有的功能外,它還允許無親緣關系進程間的通信。(2)信號(Signal):信號是在軟件層次上對中斷機制的一種模擬,它是比較復雜的通信方式,用于通知進程有某事件發(fā)生,一個進程收到一個信號與處理器收到一個中斷請求效果上可以說是一樣的。(3)消息隊列(MessgeQueue):消息隊列是消息的鏈接表,包括Posix消息隊列SystemV消息隊列。它克服了前兩種通信方式中信息量有限的缺點,具有寫權限的進程可以按照一定的規(guī)則向消息隊列中添加新消息;對消息隊列有讀權限的進程則可以從消息隊列中讀取消息。(4)共享內存(Sharedmemory):可以說這是最有效的進程間通信方式。它使得多個進程可以訪問同一塊內存空間,不同進程可以及時看到對方進程中對共享內存中數(shù)據(jù)的更新。這種通信方式需要依靠某種同步機制,如互斥鎖和信號量等。(5)信號量(Semaphore):主要作為進程之間以及同一進程的不同線程之間的同步和互斥手段。(6)套接字(Socket):這是一種更為一般的進程間通信機制,它可用于網(wǎng)絡中不同機器之間的進程間通信,應用非常廣泛。1、管道通信管道是Linux中進程間通信的一種方式,它把一個程序的輸出直接連接到另一個程序的輸入。Linux的管道主要包括兩種:無名管道和有名管道。(1)無名管道無名管道是Linux中管道通信的一種原始方法,如圖2(左圖)所示,它具有如下特點。它只能用于具有親緣關系的進程之間的通信(也就是父子進程或者兄弟進程之間)。它是一個半雙工的通信模式,具有固定的讀端和寫端。管道也可以看成是一種特殊的文件,對于它的讀寫也可以使用普通的read()、write()等函數(shù)。但是它不是普通的文件,并不屬于其他任何文件系統(tǒng),并且只存在于內存中。(2)有名管道(FIFO)有名管道是對無名管道的一種改進,如圖2(右圖)所示,它具有如下特點:它可以使互不相關的兩個進程實現(xiàn)彼此通信。該管道可以通過路徑名來指出,并且在文件系統(tǒng)中是可見的。在建立了管道之后,兩個進程就可以把它當作普通文件一樣進行讀寫操作,使用非常方便。?FIFO嚴格地遵循先進先出規(guī)則,對管道及FIFO的讀總是從開始處返回數(shù)據(jù),對它們的寫則把數(shù)據(jù)添加到末尾,它們不支持如lseek()等文件定位操作。圖2無名管道(左)和有名管道(右)2、標準流管道與Linux的文件操作中有基于文件流的標準I/O操作一樣,管道的操作也支持基于文件流的模式。這種基于文件流的管道主要是用來創(chuàng)建一個連接到另一個進程的管道,這里的“另一個進程”也就是一個可以進行一定操作的可執(zhí)行文件,例如,用戶執(zhí)行“l(fā)s-l”或者自己編寫的程序”./pipe”等。由于這一類操作很常用,因此標準流管道就將一系列的創(chuàng)建過程合并到一個函數(shù)popen()中完成。它所完成的工作有以下幾步。?創(chuàng)建一個管道。?fork()一個子進程。在父子進程中關閉不需要的文件描述符。執(zhí)行exec函數(shù)族調用。執(zhí)行函數(shù)中所指定的命令。這個函數(shù)的使用可以大大減少代碼的編寫量,但同時也有一些不利之處,例如,它不如前面管道創(chuàng)建的函數(shù)那樣靈活多樣,并且用popen()創(chuàng)建的管道必須使用標準I/O函數(shù)進行操作,但不能使用前面的read()、write()一類不帶緩沖的I/O函數(shù)。與之相對應,關閉用popen()創(chuàng)建的流管道必須使用函數(shù)pclose()來關閉該管道流。該函數(shù)關閉標準I/O流,并等待命令執(zhí)行結束。3、有名管道有名管道的創(chuàng)建可以使用函數(shù)mkfifo(),該函數(shù)類似文件中的open()操作,可以指定管道的路徑和打開的模式。(用戶還可以在命令行使用“mknod管道名P”來創(chuàng)建有名管道。)在創(chuàng)建管道成功之后,就可以使用open()、read()和write()這些函數(shù)了。與普通文件的開發(fā)設置一樣,對于為讀而打開的管道可在 open()中設置O_RDONLY,對于為寫而打開的管道可在open()中設置O_WRONLY,在這里與普通文件不同的是阻塞問題。由于普通文件的讀寫時不會出現(xiàn)阻塞問題,而在管道的讀寫中卻有阻塞的可能,這里的非阻塞標志可以在 open()函數(shù)中設定為O_NONBLOCK。下面分別對阻塞打開和非阻塞打開的讀寫進行討論。對于讀進程若該管道是阻塞打開,且當前FIFO內沒有數(shù)據(jù),則對讀進程而言將一直阻塞到有數(shù)據(jù)寫入。若該管道是非阻塞打開,則不論FIFO內是否有數(shù)據(jù),讀進程都會立即執(zhí)行讀操作。即如果FIFO內沒有數(shù)據(jù),則讀函數(shù)將立刻返回0。對于寫進程若該管道是阻塞打開,則寫操作將一直阻塞到數(shù)據(jù)可以被寫入。若該管道是非阻塞打開而不能寫入全部數(shù)據(jù)則讀操作進行部分寫入或者調用失敗4、信號量在多任務操作系統(tǒng)環(huán)境下,多個進程會同時運行,并且一些進程之間可能存在一定的關聯(lián)。多個進程可能為了完成同一個任務會相互協(xié)作,這樣形成進程之間的同步關系。而且在不同進程之間,為了爭奪有限的系統(tǒng)資源(硬件或軟件資源)會進入競爭狀態(tài),這就是進程之間的互斥關系。進程之間的互斥與同步關系存在的根源在于臨界資源。臨界資源是在同一個時刻只允許有限個(通常只有一個)進程可以訪問(讀)或修改(寫)的資源,通常包括硬件資源(處理器、內存、存儲器以及其他外圍設備等)和軟件資源(共享代碼段,共享結構和變量等)。訪問臨界資源的代碼叫做臨界區(qū),臨界區(qū)本身也會成為臨界資源。信號量是用來解決進程之間的同步與互斥問題的一種進程之間通信機制,包括一個稱為信號量的變量和在該信號量下等待資源的進程等待隊列,以及對信號量進行的兩個原子操作(PV操作)。其中信號量對應于某一種資源,取一個非負的

整型值。信號量值指的是當前可用的該資源的數(shù)量,若它等于0則意味著目前沒有可用的資源。PV原子操作的具體定義為:P操作:如果有可用的資源(信號量值>0),則占用一個資源(給信號量值減去一,進入臨界區(qū)代碼);如果沒有可用的資源(信號量值等于0),則被阻塞到,直到系統(tǒng)將資源分配給該進程(進入等待隊列,一直等到資源輪到該進程)。V操作:如果在該信號量的等待隊列中有進程在等待資源,則喚醒一個阻塞進程。如果沒有進程等待它,則釋放一個資源(給信號量值加一)。常見的使用信號量訪問臨界區(qū)的偽代碼所下所示:(/*設R為某種資源,S為資源R的信號量*/INIT_VAL(S);/*對信號量S進行初始化*/非臨界區(qū);P(S);/*進行P操作*/臨界區(qū)(使用資源R);/*只有有限個(通常只有一個)進程被允許進入該區(qū)*/V(S);/*進行V操作*/非臨界區(qū);)最簡單的信號量是只能取0和1兩種值,這種信號量被叫做二維信號量。在本節(jié)中,主要討論二維信號量。二維信號量的應用比較容易地擴展到使用多維信號量的情況。四、實驗過程、步驟及內容(一)Linux系統(tǒng)無名管道通信實驗1、創(chuàng)建新的文件目錄:$cd~/workdir/linux/application/10-comm$mkdirpipe$cdpipe2、將實驗代碼復制到新目錄下:2、將實驗代碼復制到新目錄下:linu?@ubuntu6^jvm;-/workdir/linux/applicati.or/10-connScp/nnt/hgifs/share/^^ft碼,12.\Linux系統(tǒng)無名管道通信實物/賣臉代碼/pipdpipe/-alinux@uibuntu64-vn;-/MorkdlLr/linjx/applicatiDn/10-conriS匚dpipe/Linjx@ubuntu6^-vm!-/workdlr/Itnjx/appLtcation/lfi-conn/ptpe^Ispipe^c3、編譯并執(zhí)行$gccpipe.c-opipe$./pipeccpipe.c-opipelinu)c@ubuntu64-um:worlcdir/Linux/applicatton/l&-com[n/ptpeSccpipe.c-opipeltnuK@ubuntu64-:-yworkd~Lr/LirbUx/applicattori/ia-c&nn/pipe$4、實驗代碼pipe.c#include<unistd.h>#include<stdio.h>#include<stdlib.h>intpidl,pid2;main()(intfd[2];charoutpipe[100],inpipe[100];pipe(fd); /*創(chuàng)建一個管道*/while((pid1=fork())==-1);if(pid1==0)(lockf(fd[1],1,0);sprintf(outpipe,"child1processissendingmessage!");/*把串放入數(shù)組outpipe中*/write(fd[1],outpipe,50); /*向管道寫長為50字節(jié)的串*/sleep(5); /*自我阻塞5秒*/lockf(fd[1],0,0);exit(0);)else(while((pid2=fork())==-1);if(pid2==0){ lockf(fd[1],1,0); /*互斥*/sprintf(outpipe,"child2processissendingmessage!");write(fd[1],outpipe,50);sleep(5);lockf(fd[1],0,0);exit(0);)else{wait(NULL); /*同步*/read(fd[0],inpipe,50); /*從管道中讀長為50字節(jié)的串*/printf("%s/n",inpipe);wait(NULL);read(fd[0],inpipe,50);printf("%s/n",inpipe);exit(0);))(二)Linux系統(tǒng)有名管道通信實驗1、創(chuàng)建新的文件目錄:$cd~/workdir/linux/application/10-comm$mkdirfifo$cdfifoLtnux@ubuntu64-vn:~/workdir/ltnux/dpplicatton/10-comm/pipe$cd**ltnux@ubuntu64-vn:~/workdir/ltnux/dpplicatton/10-comm$mkdirfifo2、將實驗代碼復制到新目錄下:linux@ubuntu64-vn:-/workdir/linux/application/10-conn$cp/nnt/hgfs/share/^^ft碼/13八Linux系統(tǒng)有名管道通信實鴕/賣臉代碼/cnedtE_FiFQ.c:fifo/-aLtnuK@uburitu&4-vn:-/kiorkdtr/ltnux/appltcattan/10-conin$cp 實驗代碼/13.\LinuK系統(tǒng)有名管道通信實驗/實驗代碼,「號逐d_ftf口+cfifo/-alinux^ubuntu64-vn:-/Horkdi.r/LiniiM/appitcation/IB-cohh$up/mnt/hgf3,曲白「點/實臉代碼/13.\Linux系統(tǒng)有名管道通信實覽/賣臉代碼/writu^tfof-a1inux@uibuntu&4-vn;-/workdir/linux/appltesttan/10-connScdftfa1inux£ubuntu64-wi:-/workdir/Linux/appitcation/IB-conn/fifIscreate_fifo.cread_ftfo*cwr1.te_fifo.c i3、執(zhí)行代碼$gcccreate_fifo.c-ocreate_fifo$./create_fifotest$gccread_fifo.c-oread_fifo$gccwrite_fifo.c-owrite_fifolinux@ubuntu64-vn:-/horkdir/linux/application/lO-conn/fifa$gccwrite_fifa*c-□writefifo4、實驗代碼create_fifo.c#include<stdio.h>#include<stdlib.h>#include<sys/stat.h>#include<string.h>#include<errno.h>intmain(intargc,char**argv)(if(argc<2)(fprintf(stdout,"Usage:%s<filename>\n",argv[0]);exit(1);)//intmkfifo(constchar*path,mode_tmode);if(mkfifo(argv[1],0644)<0)(fprintf(stderr,"mkfifo()failed:%s\n",strerror(errno));exit(1);)return0;)read_fifo.c#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/stat.h>#include<fcntl.h>#include<string.h>#include<errno.h>#defineBUFFER_SIZE1024intmain(intargc,char**argv)(intfd;if(argc<2)(fprintf(stdout,"Usage:%s<filename>\n",argv[0]);exit(1);)//intopen(constchar*path,intoflag,...);if((fd=open(argv[1],O_RDONLY))<0)(fprintf(stderr,"openfifo%sforreadingfailed:%s\n",argv[1],strerror(errno));exit(1);)fprintf(stdout,"openfifo%sforreadingsuccessed.\n",argv[0]);charbuffer[BUFFER_SIZE];ssize_tn;while(1)(again://ssize_tread(intfd,void*buf,size_tcount);if((n=read(fd,buffer,BUFFER_SIZE))<0)(if(errno==EINTR)(gotoagain;)else(fprintf(stderr,"readfailedon%s:%s\n",argv[1],strerror(errno));exit(1);))elseif(n==0)(fprintf(stderr,"peerclosedfifo.\n");break;)else(buffer[n]='\0';fprintf(stdout,"read%dbytesfromfifo:%s\n",n,buffer);))return0;)write_fifo.c#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/stat.h>#include<fcntl.h>#include<signal.h>#include<string.h>#include<errno.h>#defineBUFFER_SIZE1024voidsignal_handler(ints);intmain(intargc,char**argv)(intfd;if(argc<2)(fprintf(stdout,"Usage:%s<filename>\n",argv[0]);exit(1);)signal(SIGPIPE,signal_handler);//intopen(constchar*path,intoflag,...);if((fd=open(argv[1],O_WRONLY))<0)(fprintf(stderr,"openfifo%sforwrittingfailed:%s\n",argv[1],strerror(errno));exit(1);)fprintf(stdout,"openfifo%sforwrittingsuccessed.\n",argv[0]);charbuffer[BUFFER_SIZE];ssize_tn;//char*fgets(char*s,intsize,FILE*stream);while(fgets(buffer,BUFFER_SIZE,stdin))(again://ssize_twrite(intfd,constvoid*buf,size_tcount);if((n=write(fd,buffer,strlen(buffer)))<0)(if(errno==EINTR)(gotoagain;)else(fprintf(stderr,"write()failedonfifo:%s\n",strerror(errno));break;)}//endif}//endwhilereturn0;voidsignal_handler(intsigno)(fprintf(stdout,"Caughtsignal%d\n",signo);)(三)Linux系統(tǒng)信號機制實驗1、建立新的目錄并將實驗代碼復制到該目錄下$cd~/workdir/linux/application/10-comm$mkdirsignal$cdsignallinjx@uibuntu&4-vm:~/workdtr/ltnuxyappltcatton/ie-connSmkdtrsignallinux@uibuntu&4-vm:~/wa「kdi「八inux,application/Ifl-8nM5cp/nnt/hgfs/shd「號,實.驗代碼JLL\Linux系統(tǒng)信號機制賣覽/實臉代碼/signal.匚signal/-alinkJX@Libuntu&4-vn;~/wQrkdir/linux/application/10-CQnmScdsignal/liniDc9ubuntu54-vni-/workdir/Linux/application/16-conn/signalfIssignal.clinux@uibuntu64vh:-/workdir/ltnux/opplicdtion/10-connysignals2、編譯代碼:$gccsignal.c-osignalltnuxQubuntuC4-VH:^/workdtr/llnux/appllcatlon/w-comn/stgnal$gccsignal.c-osgnallinux@ubuntu64-VMi-,wc>「kdi「,linux/dpplic:dtton,lD-Eorrim/si9nm'l$*/signal3、實驗代碼:signal.c#include<stdio.h>#include<signal.h>#include<unistd.h>#include<stdlib.h>intwait_mark;voidwaiting(),stop();intmain(intargc,char*argv口)(intpl,p2;signal(SIGINT,stop);while((p1=fork())==-1);if(pl>0) /*在父進程中*/(while((p2=fork())==-1);if(p2>0) /*在父進程中*/(wait_mark=1;waiting();kill(p1,10);kill(p2,12);wait(NULL);wait(NULL);printf("parentprocessexit!\n");exit(0);)else /*在子進程2中*/(wait_mark=1;signal(12,stop);waiting();lockf(1,1,0);printf("childprocess2iskilledbyparent!\n");lockf(1,0,0);exit(0);))else /*在子進程1中*/(wait_mark=1;signal(10,stop);waiting();lockf(1,1,0);printf("childprocess1iskilledbyparent!\n");lockf(1,0,0);exit(0);))voidwaiting()(while(wait_mark!=0);)voidstop()(wait_mark=0;)(四)Linux系統(tǒng)共享內存通信實驗1、創(chuàng)建新的文件夾,并把實驗代碼復制到該目錄下:$cd~/workdir/linux/application/10-comm$mkdirshmem$cdshmem

signal(SIGUSR1,handler);if((key=ftok(".",'a'))<0)(perror("failtoftok");exit(-1);)if((shmid=shmget(key,sizeof(shmbuf),IPC_CREAT|IPC_EXCL|0666))<0)(if(errno==EEXIST)(shmid=shmget(key,sizeof(shmbuf),0666);shmaddr=(shmbuf*)shmat(shmid,NULL,0);pid=shmaddr->pid;shmaddr->pid=getpid();kill(pid,SIGUSR1);)else(perror("failtoshmget");exit(-1);))else(shmaddr=(shmbuf*)shmat(shmid,NULL,0);shmaddr->pid=getpid();pause();pid=shmaddr->pid;)while(1)(pause();if(strncmp(shmaddr->buf,"quit",4)==0)(break;);printf("messagefromshm:%s",shmaddr->buf);usleep(100000);kill(pid,SIGUSR1);)shmdt(shmaddr);return0;)writer.c#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/shm.h>#include<sys/ipc.h>#include<unistd.h>#include<signal.h>#include<errno.h>#defineN64typedefstruct(intpid;charbuf[N];}shmbuf;voidhandler(intsigno)(return;}intmain(intargc,char*argv口)(intshmid;key_tkey;pid_tpid;shmbuf*shmaddr;signal(SIGUSR1,handler);if((key=ftok(".",'a'))<0)(perror("failtoftok");exit(-1);}if((shmid=shmget(key,sizeof(shmbuf),IPC_CREAT|IPC_EXCL|0666))<0)(if(errno==EEXIST)(shmid=shmget(key,sizeof(shmbuf),0666);shmaddr=(shmbuf*)shmat(shmid,NULL,0);pid=shmaddr->pid;shmaddr->pid=getpid();kill(pid,SIGUSR1);)else(perror("failtoshmget");exit(-1);))else(shmaddr=(shmbuf*)shmat(shmid,NULL,0);shmaddr->pid=getpid();pause();pid=shmaddr->pid;)while(1)(printf("pleaseinput:");fgets(shmaddr->buf,N,stdin);kill(pid,SIGUSR1);if(strncmp(shmaddr->buf,"quit",4)==0)(break;)pause();)sleep(1);shmdt(shmaddr);shmctl(shmid,IPC_RMID,NULL);return0;)(五)Linux系統(tǒng)消息隊列實驗1、創(chuàng)建新的目錄,并把實驗代碼復制到該目錄下$cd~/workdir/linux/application/10-comm$mkdirmsg$cdmsgItnux@ubuntu64-vn:-Scdworkdtr/Linux/appLLcation/ID-comAltnuK@ubuntu64-vn:-/workdir/ltnux/applteatlon/10-coringnkdtrmsg1inu^@ubuntu64-vni-/workdir/Hnux/application/lO-cnmScp/nnt/hgfs/shars/實驗代碼/28.\Linux系統(tǒng)消息隊列實擅/實驗代里/clientlcttentlcltentl.c/nnt/hgf5/5ha「"實般代"nt/hgfe/sh0「“實驗代/pint/h9f5/5h司i■”實驗代/Ent/hgfM"hm「e/實騙代E皿ltnux@ut)untu64-vn:~/workclir/linuK/dpplicatiori/10-connScp研"£L\Linux/nnt/hgf5/5ha「"實般代"nt/hgfe/sh0「“實驗代/pint/h9f5/5h司i■”實驗代/Ent/hgfM"hm「e/實騙代E皿\inun@ubuntu64-vn;-/i^orkdtr/linux/application/io-com/nsg$|2、編譯代碼:$gccclientl.c-oclientl$gccclient2.c-oclient2$gccserver.c-oserverlinux@ubuntu&4-vni-/workdiry-LiriUx/applicati&n/lO-c&mn/nsgSgccclientl-c-acliintlclientl.c;在函數(shù)'mdin'中:clientl+c;25:警告:不建議便用RutM(聲明于/u5「/includc,5tdi0.h:638)linux@ubuntu&4-vni-/workdiry-LiriUM/applicati&n^lO-c&mn/nsgJgccclients.c-acliint2clients.c;在函敷中:clientZ.c:33;曾告:不建議使用‘guts'(聲明于/usr/tnclude/stdto.li.nijx@ub!jntu&4-vn:/workd'ir/linux/applicati&n/io-c&nn/nsgjgccservers-oservi「ltnux@ubuntu54-vn:-/kiorkdlr/Hridx/appltcattori/10-ct)nn/nsg$3、實驗代碼:Server.c#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<string.h>#defineKEY_MSG0x101 //使用共有的IPCkey#defineMSGSIZE64typedefstruct 〃定義消息結構體:消息類型和消息數(shù)據(jù)(longmtype;charmtext[MSGSIZE];}msgbuf;#defineLENsizeof(msgbuf)-sizeof(long)intmain()(intmsgid;msgbufbufl,buf2;msgid=msgget(KEY_MSG,IPC_CREAT|0666);while(l)(msgrcv(msgid,&buf1,LEN,1L,0);〃接受客戶端1的消息printf("Receiveclient1message:%s\n",buf1.mtext);〃打印收到的消息if(buf1.mtext[0]=='x'||buf1.mtext[0]=='X')〃若是退出標志,則給2個客戶端都發(fā)退出信息{strcpy(buf1.mtext,"x");buf1.mtype=3L;msgsnd(msgid,&buf1,LEN,0);buf1.mtype=4L;msgsnd(msgid,&buf1,LEN,0);break;)buf1.mtype=4L;msgsnd(msgid,&buf1,LEN,0); 〃將客戶端1的消息轉發(fā)給客戶端2msgrcv(msgid,&buf2,LEN,2L,0);〃接受客戶端2的消息printf("Receiveclient2message:%s\n",buf2.mtext);//打印收到的消息if(buf2.mtext[0]=='x'||buf2.mtext[0]=='X')//若是退出標志,則給2個客戶端發(fā)退出信息{strcpy(buf2.mtext,"x");buf2.mtype=3L;msgsnd(msgid,&buf2,LEN,0);buf2.mtype=4L;msgsnd(msgid,&buf2,LEN,0);break;)buf2.mtype=3L;msgsnd(msgid,&buf2,LEN,0); 〃將客戶端2的消息轉發(fā)給客戶端1)sleep(1); //若退出,則先等待,以確??蛻舳顺绦蛲顺鰉sgctl(msgid,IPC_RMID,NULL);//刪除消息隊列,釋放空間exit(0);)Client1.c#include<stdio.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<string.h>#defineKEY_MSG0x101#defineMSGSIZE64typedefstruct(longmtype;charmtext[MSGSIZE];}msgbuf;#defineLENsizeof(msgbuf)-sizeof(long)intmain()(intmsgid;msgbufbuf1,buf2;msgid=msgget(KEY_MSG,0666);while(1){printf("inputthemsgtoclient2:");gets(buf1.mtext);buf1.mtype=1L;msgsnd(msgid,&buf1,LEN,0);//客戶端1獲取消息并發(fā)往服務器msgrcv(msgid,&buf2,LEN,3L,0);//準備從客戶端2獲取消息if(buf2.mtext[0]=='x'||buf2.mtext[0]=='X'){printf("client1willquit!\n");break;}printf("Receivefromclient2,message:%s\n",buf2.mtext);}return0;}Client2.c#include<stdio.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<string.h>#defineKEY_MSG0x101#defineMSGSIZE64typedefstruct{longmtype;charmtext[MSGSIZE];}msgbuf;#defineLENsizeof(msgbuf)-sizeof(long)intmain()(intmsgid;msgbufbuf1,buf2;msgid=msgget(KEY_MSG,0666);while(1)( 一msgrcv(msgid,&buf2,LEN,4L,0);〃等待客戶端1發(fā)消息if(buf2.mtext[0]=='x'||buf2.mtext[0]=='X')(printf("client2willquit!\n");break;}elseprintf("Receivefromclient1,message:%s\n",buf2.mtext);sleep(1);〃等待一秒,以確保客戶端1已經(jīng)收到了回執(zhí)printf("inputthemsgtoclient1:");gets(buf1.mtext);buf1.mtype=2L;msgsnd(msgid,&buf1,LEN,0);〃給客戶端1發(fā)送回執(zhí)消息}}五、實驗數(shù)據(jù)(現(xiàn)象)處理分析(一)Linux系統(tǒng)無名管道通信實驗運行結果,延遲5秒后顯示:child1processissendingmessage!再顯示:child2processissendingmessage!Linux@ut>untiJ64-vn:~/workdir/Linux/appLication/lO-conH/pipe5,/pipechild1processissendingnesssge!/nchild2processt5sendingnessagel/nlinuxubuntLi64-vn:~/workdtr/ltnux/appHcatton/10-camn/pipe$|(二)Linux系統(tǒng)有名管道通信實驗$./read_fifotest〃執(zhí)行讀管道文件的程序打開另一個終端,進入該目錄$./wirte_fifo〃執(zhí)行寫管道文件的程序寫入helloopenfifo./write_fifoforwrittingsuccessed.hellollnuxgubuntu^-vn:~;uiorkrltr/ltnux/dppltcdtton/10-conm/firoS卜/reacl_f1fotestopenftfo./rread_ftfofciir「EdtJlnqsuccessed.Iinu^@ubuntu64-7m1-Scdworkdtr/li.nux/cpplicatton/lO-conn/fif□/LtnuK@utiuntu64-i/m:-/workditr/ltnuM/dppltcatton/lo-comm/ftfaS./rwrtte_ftfoJsage:*/write_fifo<filenane>linux@ubuntu64-7n:-/Norkdtr/l.inux/dpplication/10-conn/fifo5■/write_fifotestapenftfo./wrtte_ftfoforwrttttriigsuccessed.helloI LibreOFFiceImpressopenftfo./redd_rtfoforreadingsuccessed*read6bytesfron

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論