實驗五進程間通信(DOC)_第1頁
實驗五進程間通信(DOC)_第2頁
實驗五進程間通信(DOC)_第3頁
實驗五進程間通信(DOC)_第4頁
實驗五進程間通信(DOC)_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、實驗五 進程間通信unix/linux系統(tǒng)的進程間通信機構(gòu)(ipc)允許在任意進程間大批量地交換數(shù)據(jù)。本實驗的目的是了解和熟悉linux支持的信號機制、管道機制、消息隊列通信機制及共享存儲區(qū)機制。5.1信號機制實驗(一)【實驗?zāi)康摹?了解什么是信號。2熟悉linux系統(tǒng)中進程之間軟中斷通信的基本原理?!緦嶒炘怼坷胹ignal來實現(xiàn)發(fā)送信號和接受信號的原理【實驗內(nèi)容】1編寫一段程序,使用系統(tǒng)調(diào)用fork( )創(chuàng)建兩個子進程,再用系統(tǒng)調(diào)用signal( )讓父進程捕捉鍵盤上來的中斷信號(即按ctrl+c鍵),當捕捉到中斷信號后,父進程用系統(tǒng)調(diào)用kill( )向兩個子進程發(fā)出信號,子進程捕捉到父

2、進程發(fā)來的信號后,分別輸出下列信息后終止: child process 1 is killed by parent!child process 2 is killed by parent!父進程等待兩個子進程終止后,輸出以下信息后終止: parent process is killed! # include# include# includeint wait_mark;void waiting(),stop();void main() int p1, p2;signal(sigint,stop);while(p1=fork()=-1);if(p10)/*在父進程中*/ while(p2=for

3、k()= =-1); if(p20)/*在父進程中*/ wait_mark=1; waiting(0); kill(p1,10); kill(p2,12); wait( ); wait( ); printf(“parent process is killed!n”); exit(0); else/*在子進程2中*/ wait_mark=1;signal(12,stop);waiting();lockf(1,1,0);printf(“child process 2 is killed by parent!n”);lockf(1,0,0);exit(0); else/*在子進程1中*/ wait_

4、mark=1; signal(10,stop); waiting(); lockf(1,1,0); printf(“child process 1 is killed by parent!n”); lockf(1,0,0); exit(0);void waiting() while(wait_mark!=0);void stop() wait_mark=0;實驗要求: 運行程序并分析結(jié)果。 如果把signal(sigint,stop)放在號和號位置,結(jié)果會怎樣并分析原因。 該程序段前面部分用了兩個wait(0),為什么? 該程序段中每個進程退出時都用了語句exit(0),為什么?5.2信號機制

5、實驗(二)【實驗?zāi)康摹繉W習signal的函數(shù)的使用【實驗原理】利用signal的函數(shù)的機制來實習我們發(fā)送截獲信號的功能【實驗內(nèi)容】修改上面的程序,增加語句signal(sigint,sig_ign)和語句signal(sigquit,sig_ign),再觀察程序執(zhí)行時屏幕上出現(xiàn)的現(xiàn)象,并分析其原因。# include# include# includeint pid1, pid2;int endflag=0;pf1=0;pf2=0;void intdelete() kill(pid1,10); kill(pid2,12);endflag=1;void int1() printf(“child

6、process 1 is killed by parent !n”); exit(0);void int2() printf(“child process 2 is killed by parent !n”); exit(0);main() int exitcode; signal(sigint,sig_ign); signal(sigquit,sig_ign);while(pid1=fork()=-1); if(pid1=0) signal(sigusr1,int1);signal(sigint,sig_ign);pause();exit(0); else while(pid2=fork()

7、= =-1); if(pid2=0) signal(sigusr2,int2);signal(sigint,sig_ign);pause();exit(0); else signal(sigint,intdelete); waitpid(-1,&exitcode,0);/*等待任何子進程中斷或結(jié)束*/ printf(“parent process is killed n”); exit(0); 實驗要求:運行程序并分析結(jié)果。司機售票員問題(選做題)編程用fork()創(chuàng)建一個子進程代表售票員,司機在父進程中,再用系統(tǒng)調(diào)用signal()讓父進程(司機)捕捉來自子進程(售票員)發(fā)出的中斷信號,讓子

8、進程(售票員)捕捉來自(司機)發(fā)出的中斷信號,以實現(xiàn)進程間的同步運行。5.3管道通信實驗(一)【實驗?zāi)康摹?、了解什么是管道2、熟悉unix/linux支持的管道通信方式【實驗內(nèi)容】編寫程序?qū)崿F(xiàn)進程的管道通信。用系統(tǒng)調(diào)用pipe( )建立一管道,二個子進程p1和p2分別向管道各寫一句話: child 1 is sending a message! child 2 is sending a message!父進程從管道中讀出二個來自子進程的信息并顯示(要求先接收p1,后p2)。參考程序#include #include #include int pid1,pid2;main( ) int fd2

9、;char outpipe100,inpipe100;pipe(fd); /*創(chuàng)建一個管道*/while (pid1=fork( )= =-1);if(pid1= =0)lockf(fd1,1,0); sprintf(outpipe,child 1 process is sending message!); /*把串放入數(shù)組outpipe中*/ write(fd1,outpipe,50); /*向管道寫長為50字節(jié)的串*/ sleep(5); /*自我阻塞5秒*/ lockf(fd1,0,0); exit(0);elsewhile(pid2=fork( )= =-1); if(pid2= =0

10、) lockf(fd1,1,0); /*互斥*/ sprintf(outpipe,child 2 process is sending message!); write(fd1,outpipe,50); sleep(5);lockf(fd1,0,0); exit(0); else wait(0); /*同步*/ read(fd0,inpipe,50); /*從管道中讀長為50字節(jié)的串*/ printf(%s/n,inpipe); wait(0); read(fd0,inpipe,50); printf(%s/n,inpipe); exit(0); 五、運行結(jié)果 延遲5秒后顯示child 1 p

11、rocess is sending message! 再延遲5秒child 2 process is sending message!5.4管道通信實驗(二)【實驗?zāi)康摹?、掌握有名管道的創(chuàng)建和讀寫方式2、熟悉unix/linux支持的有名管道通信方式【實驗內(nèi)容】1. 創(chuàng)建有名管道2. 本進程執(zhí)行循環(huán)等待數(shù)據(jù)被寫入到管道中并讀有名管道3. 打開有名管道并寫數(shù)據(jù)到名管道參考代碼:/read_fifo.c#include #include #include #include #include #include #include #define buffer_size1024int main(int

12、 argc, char *argv) int fd; if (argc 2) fprintf(stdout, usage: %s n, argv0); exit(1); /int open(const char *path, int oflag, .); if (fd = open(argv1, o_rdonly) 0) fprintf(stderr, open fifo %s for reading failed: %sn, argv1, strerror(errno); exit(1); fprintf(stdout, open fifo %s for reading successed.

13、n, argv0); char bufferbuffer_size; ssize_t n; while (1) again: /ssize_t read(int fd, void *buf, size_t count); if (n = read(fd, buffer, buffer_size) 0) if (errno = eintr) goto again; else fprintf(stderr, read failed on %s: %sn, argv1, strerror(errno);exit(1); else if (n = 0) fprintf(stderr, peer clo

14、sed fifo.n); break; else buffern = 0; fprintf(stdout, read %d bytes from fifo: %sn, n, buffer); return 0;/ write_fifo.c#include #include #include #include #include #include #include #include #define buffer_size1024void signal_handler(int s);int main(int argc, char *argv) int fd; if (argc 2) fprintf(

15、stdout, usage: %s n, argv0); exit(1); signal(sigpipe, signal_handler); /int open(const char *path, int oflag, .); if (fd = open(argv1, o_wronly) 0) fprintf(stderr, open fifo %s for writting failed: %sn, argv1, strerror(errno); exit(1); fprintf(stdout, open fifo %s for writting successed.n, argv0); c

16、har bufferbuffer_size; ssize_t n; /char *fgets(char *s, int size, file * stream); while (fgets(buffer, buffer_size, stdin) again: /ssize_t write(int fd, const void *buf, size_t count); if (n = write(fd, buffer, strlen(buffer) 0) if (errno = eintr) goto again; else fprintf(stderr, write() failed on f

17、ifo: %sn, strerror(errno);/ fixme:break; return 0;void signal_handler(int s) fprintf(stdout, caught signal %dn, s);/ create_fifo.c#include #include #include #include #include int main(int argc, char *argv) if (argc 2) fprintf(stdout, usage: %s n, argv0); exit(1); /int mkfifo(const char *path, mode_t

18、 mode); if (mkfifo(argv1, 0644) 0) fprintf(stderr, mkfifo() failed: %sn, strerror(errno); exit(1); return 0;5.5共享內(nèi)存通信實驗【實驗?zāi)康摹?、掌握共享內(nèi)存的創(chuàng)建和讀寫方式2、熟悉unix/linux支持的共享內(nèi)存通信方式【實驗內(nèi)容】1. 創(chuàng)建共享內(nèi)存2. 寫入到共享內(nèi)存3. 讀數(shù)據(jù)從共享內(nèi)存代碼參考:/write.c#include #include #include #include #include #include #include #include #include #def

19、ine mapped_filename/tmp/test.mmap.1int main(int argc, char *argv) int fd; if (argc 2) fprintf(stdout, usage: %s n, argv0); exit(1); / xxx: step 1, open file, get a fd /int open(const char *pathname, int flags, mode_t mode); if (fd = open(argv1, o_rdwr | o_creat | o_excl, 0644) 0) if (errno = eexist)

20、 fprintf(stderr, fatal error: the target mapped file existed, exit.n); else fprintf(stderr, error: open file failed: (errno = %d)%sn, errno, strerror(errno); exit(1); off_t offset; offset = 1024; / xxx: step 2, create a hole file /off_t lseek(int fildes, off_t offset, int whence); if (lseek(fd, offs

21、et, seek_set) = (off_t) - 1) fprintf(stderr, lseek() failed: %sn, strerror(errno); /fixme: unlink the file close(fd); exit(1); ssize_t n; /ssize_t write(int fd, const void *buf, size_t count); if (n = write(fd, , 1) 0) fprintf(stderr, write() failed: %sn, strerror(errno); exit(1); /* * on success, m

22、map returns a pointer to the mapped area. on error, the value map_failed (that is, (void*) -1) is returned, and errno is set appropriately. on success, munmap returns 0, on failure -1, and errno is set (probably to einval). */* prot_exec pages may be executed. prot_read pages may be read. prot_write

23、 pages may be written. prot_none pages may not be accessed.*/ void *p; / xxx: step 3, mmap(), get a pointer /void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset); if (p = mmap(null, 1024, prot_write, map_shared, fd, 0) = map_failed) fprintf(stderr, mmap() failed: %sn,

24、strerror(errno); close(fd); exit(1); close(fd); fprintf(stdout, mapped file to memory, size = %dn, 1024); / xxx: step 4, read/write on shared memory char *banner = hello world.; /void *memcpy(void *dest, const void *src, size_t n); memcpy(p + 256, banner, strlen(banner); / xxx: step 5, munmap(); /in

25、t munmap(void *start, size_t length); pause(); /close(fd); return 0;/ read.c#include #include #include #include #include #include #include #include #include #define mapped_filename/tmp/test.mmap.1#define buffer_size1024int main(int argc, char *argv) int fd; if (argc 2) fprintf(stdout, usage: %s n, a

26、rgv0); exit(1); / xxx: step 1, open file, get a fd /int open(const char *pathname, int flags, mode_t mode); if (fd = open(argv1, o_rdwr) 0) fprintf(stderr, error: open file failed: (errno = %d)%sn, errno, strerror(errno); exit(1); #if 0 off_t offset; offset = 1024; / xxx: step 2, create a hole file

27、/off_t lseek(int fildes, off_t offset, int whence); if (lseek(fd, offset, seek_set) = (off_t) - 1) fprintf(stderr, lseek() failed: %sn, strerror(errno); /fixme: unlink the file close(fd); exit(1); ssize_t n; /ssize_t write(int fd, const void *buf, size_t count); if (n = write(fd, , 1) 0) fprintf(std

28、err, write() failed: %sn, strerror(errno); exit(1); #endif /* * on success, mmap returns a pointer to the mapped area. on error, the value map_failed (that is, (void*) -1) is returned, and errno is set appropriately. on success, munmap returns 0, on failure -1, and errno is set (probably to einval).

29、 */* prot_exec pages may be executed. prot_read pages may be read. prot_write pages may be written. prot_none pages may not be accessed.*/ void *p; / xxx: step 3, mmap(), get a pointer /void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset); if (p = mmap(null, 1024, prot

30、_write, map_shared, fd, 0) = map_failed) fprintf(stderr, mmap() failed: %sn, strerror(errno); close(fd); exit(1); close(fd); fprintf(stdout, mapped file to memory, size = %dn, 1024); char bufferbuffer_size; / xxx: step 4, read/write on shared memory /void *memcpy(void *dest, const void *src, size_t

31、n); memcpy(buffer, p+256, 32); fprintf(stdout, %sn, buffer); / xxx: step 5, munmap(); /int munmap(void *start, size_t length); /close(fd); return 0;5.6用消息隊列編寫一個客戶端服務(wù)器通信的程序【實驗?zāi)康摹客ㄟ^此實驗,學員可以熟悉消息隊列的概念,并能夠用消息隊列編寫一個客戶端服務(wù)器通信的程序?!緦嶒炘怼勘緦嶒炐枰孟㈥犃性O(shè)計一個簡易的雙人聊天程序(一個服務(wù)器,兩個客戶端)。消息隊列重點在于消息類型的匹配,客戶端和服務(wù)端的“通信協(xié)議”的設(shè)計。設(shè)計

32、思想如下:服務(wù)器端:接受客戶端發(fā)來的任何信息,并根據(jù)其消息類型,轉(zhuǎn)發(fā)給對應(yīng)的客戶端。同時,檢測是否有退出標志,有則給所有的客戶端發(fā)送退出標志,等待10s后,確定客戶端都退出后,刪除消息隊列,釋放空間,并退出??蛻舳耍篴和b,a給b發(fā)送信息,先發(fā)給服務(wù)器,由服務(wù)器根據(jù)自定義協(xié)議轉(zhuǎn)發(fā)該消息給b。同時b接受到消息后,經(jīng)由服務(wù)器給a一個回執(zhí)信息,以此形成簡易的聊天模式?!緦嶒灧椒ā烤帉懛?wù)器端程序:#define key_msg 0x101 /使用共有的ipc key#define msgsize 128#include #include #include #include #include main

33、() int msgid; struct msgbuf /定義消息結(jié)構(gòu)體:消息類型和消息數(shù)據(jù) long mtype; char mtext128; buf1, buf2; msgid = msgget( key_msg, ipc_creat|0666 ); while( 1 ) /無限循環(huán),退出標志則會break msgrcv( msgid, &buf1, msgsize, 1l, 0 ); /接受客戶端1的消息printf( receive client1 message: %sn, buf1.mtext ); /打印收到的消息if( buf1.mtext0 = x | buf1.mtext

34、0 = x ) /若是退出標志,則給2個客戶端都發(fā)退出信息 strcpy( buf1.mtext, x ); buf1.mtype = 3l; msgsnd( msgid, &buf1, msgsize, 0 ); buf1.mtype = 4l; msgsnd( msgid, &buf1, msgsize, 0 ); break; buf1.mtype = 4l;msgsnd( msgid, &buf1, msgsize, 0 ); /將客戶端1的消息轉(zhuǎn)發(fā)給客戶端2 msgrcv( msgid, &buf2, msgsize, 2l, 0 ); /接受客戶端2的消息printf( recei

35、ve client2 message: %sn, buf2.mtext ); /打印收到的消息if( buf2.mtext0 = x | buf2.mtext0 = x )/若是退出標志,則給2個客戶端發(fā)退出信息 strcpy( buf2.mtext, x ); buf2.mtype = 3l; msgsnd( msgid, &buf2, msgsize, 0 ); buf2.mtype = 4l; msgsnd( msgid, &buf2, msgsize, 0 ); break; buf2.mtype = 3l;msgsnd( msgid, &buf2, msgsize, 0 ); /將客

36、戶端2的消息轉(zhuǎn)發(fā)給客戶端1 sleep(5); /若退出,則先等待,以確??蛻舳顺绦蛲顺?msgctl( msgid, ipc_rmid, null ); /刪除消息隊列,釋放空間 exit(0);客戶端1:#define key_msg 0x101#define msgsize 128#include #include #include #include #include main() int msgid; struct msgbuf long mtype; char mtext128; buf1, buf2; msgid = msgget( key_msg, 0666 ); while( 1 ) printf( input the msg to client2: ); gets( buf1.mtext ); buf1.mtype = 1l; msgsnd( msgid, &buf1, msgsize, 0 ); /客戶端1獲取消息并發(fā)往服務(wù)器sleep(1); /等待一秒,以確??蛻舳?已經(jīng)收到并發(fā)了回執(zhí) msgrcv( msgid, &buf2, msgsize, 3l, 0 ); /準備從客戶端2獲取回執(zhí)消息 if( buf2.mtext0 = x | buf2.mtext0 = x ) printf( client1 will quit!n ); break; p

溫馨提示

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

評論

0/150

提交評論