實驗三、進程通信(一)——管道及共享內存_第1頁
實驗三、進程通信(一)——管道及共享內存_第2頁
實驗三、進程通信(一)——管道及共享內存_第3頁
實驗三、進程通信(一)——管道及共享內存_第4頁
實驗三、進程通信(一)——管道及共享內存_第5頁
已閱讀5頁,還剩8頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

1、操作系統實驗報告實驗三、進程通信(一)管道及共享內存一、實驗目的1) 加深對管道通信的了解2) 掌握利用管道進行通信的程序設計3) 了解共享內存通信的程序設計方法4) 了解和熟悉 linux 支持的共享存儲區機制二、實驗內容任務一、(1)閱讀以上父子進程利用管道進行通信的例子(例1) ,寫出程序的運行結果并分析。(2)編寫程序: 父進程利用管道將一字符串交給子進程處理。子進程讀字符串,將里面的字符反向后再交給父進程,父進程最后讀取并打印反向的字符串。任務二、(1)閱讀例 2 的程序,運行一次該程序,然后用ipcs 命令查看系統中共享存儲區的情況,再次執行該程序,再用ipcs 命令查看系統中共享

2、內存的情況,對兩次的結果進行比較, 并分析原因。最后用 ipcrm 命令刪除自己建立的共享存儲區。(有關 ipcs 和 ipcrm 介紹見后面一頁)(2)每個同學登陸兩個窗口,先在一個窗口中運行例3 程序 1(或者只登陸一個窗口,先在該窗口中以后臺方式運行程序1) ,然后在另一個窗口中運行例3程序 2,觀察程序的運行結果并分析。運行結束后可以用ctrl+c 結束程序 1 的運行。(3)編寫程序:使用系統調用 shmget(),shmat(),shmdt(),shmctl(),編制程序。要求在父進程中生成一個30 字節長的私有共享內存段。接下來,設置一個指向共享內存段的字符指針, 將一串大寫字母

3、寫入到該指針指向的存貯區。調用 fork()生成子進程,讓子進程顯示共享內存段中的內容。接著,將大寫字母改成小寫,子進程修改共享內存中的內容。之后,子進程將脫接共享內存段并退出。父進程在睡眠 5 秒后,在此顯示共享內存段中的內容(此時已經是小寫字母)。三、代碼及運行結果分析(1)閱讀以上父子進程利用管道進行通信的例子(例 1) ,寫出程序的運行結果并分析實驗代碼:#includemain() int x,fd2; char buf30,s30; pipe(fd); while (x=fork()=-1); if (x=0) close(fd0); printf(child process!n)

4、; strcpy(buf,this is an examplen); write(fd1,buf,30); exit(0); else close(fd1); printf(parent process!n); read(fd0,s,30); printf(%sn,s); 運行結果:分析:調用 pipe(fd);創建一個管道后,接著調用fork()函數產生兩個進程,首先開始執行子進程,關閉管道出口,通過管道入口向管道中寫入內容。執行if 語句后,進入 else語句塊內開始父進程, 管道入口關閉, 通過管道出口端從管道中讀取之前寫入內容,最后輸出出來(2)編寫程序:父進程利用管道將一字符串交給子

5、進程處理。子進程讀字符串,將里面的字符反向后再交給父進程,父進程最后讀取并打印反向的字符串。實驗代碼:#include main() int x,count,left,right,temp,fd2,fe2; char c,buf30,s30; pipe(fd); pipe(fe); printf(please input a line of char); scanf(%s,buf); while(x=fork()=-1); if(x=0) close(fd0); close(fe1); printf(child process!n); write(fd1,buf,30); read(fe0,b

6、uf,30); printf(%sn,buf); exit(0); else close(fd1); close(fe0); count=0; do read(fd0,&c,1); scount+=c; while(c!=0); printf(parent process!n); printf(%sn,s); count-=2; for(left=0,right=count;left=count/2;left+,right-) temp=sleft; sleft=sright; sright=temp; write(fe1,s,30); wait(0); 運行結果:(3)閱讀例 2 的

7、程序,運行一次該程序,然后用ipcs命令查看系統中共享存儲區的情況,再次執行該程序,再用ipcs命令查看系統中共享內存的情況,對兩次的結果進行比較,并分析原因。最后用ipcrm 命令刪除自己建立的共享存儲區。(有關 ipcs和 ipcrm 介紹見后面一頁)實驗代碼:#include #include #include main() key_t key=208; /*在實際實驗過程中,為了避免每個同學建立的共享存儲區關鍵字一樣而相互干擾,關鍵字請用學號末3 位*/ int shmid_1,shmid_2; if (shmid_1=shmget(key,1000,0644|ipc_creat)=-

8、1) perror(shmget shmid_1);exit(1); printf(first shared memory identifier is %dn,shmid_1); if (shmid_2=shmget(ipc_priv ate,20,0644)=-1) perror(shmget shmid_2);exit(2); printf(second shared memory identifier is %dn,shmid_2); exit(0); 運行結果:ipcs 查看:再次運行:再次用 ipcs查看:ipcrm 刪除分析:成功,返回共享內存段的標識符, 內核中用于唯一的標識一個

9、對象。對存在于內核存貯空間中的每個共享內存段,內核均為其維護著一個數據結構shmid_ds。失敗,返回 1,設置 errno。第一個參數key(鍵值)用來創建ipc 標識符, shmget() 返回的標識符與key 值一一對應,不同的key 值返回不同的標識符。第二個參數 size,決定了共享內存段的大小(若訪問已存在的內存段,該參數可設為 0) 。有最大字節數的限制第三個參數 shmflag,用于設置訪問權限及標識創建條件。對兩次的結果進行比較:兩次運行結束后的第二個共享標識符是不一樣的。在用 ipcs 查看時,共享內存段中的關鍵字,共享內存標識符,訪問權限,字節等都是不一樣的。(4)每個同

10、學登陸兩個窗口,先在一個窗口中運行例3 程序 1(或者只登陸一個窗口,先在該窗口中以后臺方式運行程序1) ,然后在另一個窗口中運行例3 程序 2,觀察程序的運行結果并分析。運行結束后可以用ctrl+c 結束程序1 的運行。實驗代碼:#include #include #include #define shmkey 208 /*在實際實驗過程中, 為了避免每個同學建立的共享存儲區關鍵字一樣而相互干擾,關鍵字請用學號末3 位*/ #define k 1024 int shmid; main () int i,*pint; char *addr; extern char * shmat (); ex

11、tern cleanup (); for(i=0;i20;i+) signal(i,cleanup); shmid=shmget(shmkey,16*k,0777|ipc_creat); /*建立 16k 共享區 shmkey */ addr=shmat(shmid,0,0);/* 掛接,并得到共享區首地址*/ printf (addr 0 x%xn,addr); pint=(int *)addr; for (i=0;i256;i+) *pint+=i; pause();/*等待接收進程讀*/ cleanup() shmctl(shmid,ipc_rmid,0); exit (); 運行結果:

12、分析:首先系統通過調用shmctl 對 shmid 指向的內存段進行刪除操作,接著系統調用shmget 創建一個 16*1024 字節的共享內存段,成功返回共享內存段的標識符給shmid,系統再次調用shmat 連接內存段,返回該共享內存段連接到調用進程地址空間上的地址 addr。實驗代碼:#include #include #include #define shmkey 208 /*在實際實驗過程中, 為了避免每個同學建立的共享存儲區關鍵字一樣而相互干擾,關鍵字請用學號末3 位*/ #define k 1024 int shmid; main () int i,*pint; char *ad

13、dr; extern char * shmat (); shmid=shmget(shmkey,8*k,0777);/*取共享區shmkey的 id */ addr=shmat(shmid,0,0);/* 連接共享區 */ pint=(int *)addr; for (i=0;i256;i+) printf(%dn,*pint+);/*打印共享區中的內容*/ 運行結果:分析:例 3_1 程序后臺運行時, 該程序開始執行, 系統調用 shmget創建一個 8*1024 字節的共享內存段,再通過調用shmat掛接內存段,由系統選擇掛接地址,最終輸出轉換后的掛接地址。需要指出的是, 共享存儲區機制只

14、為通信進程提供了訪問共享存儲區的操作條件,而對通信的同步控制則要依靠信號量機制等才能完成。(5)編寫程序:使用系統調用shmget(),shmat(),shmdt(),shmctl(),編制程序。要求在父進程中生成一個30 字節長的私有共享內存段。接下來,設置一個指向共享內存段的字符指針,將一串大寫字母寫入到該指針指向的存貯區。調用fork()生成子進程, 讓子進程顯示共享內存段中的內容。接著, 將大寫字母改成小寫, 子進程修改共享內存中的內容。之后,子進程將脫接共享內存段并退出。父進程在睡眠5 秒后,在此顯示共享內存段中的內容(此時已經是小寫字母)。實驗代碼:#include #includ

15、e #include #define shmkey 208 /*在實際實驗過程中, 為了避免每個同學建立的共享存儲區關鍵字一樣而相互干擾,關鍵字請用學號末3 位*/ #define k 1024 int shmid; main() int i; char *pint; char *addr; extern char * shmat (); extern cleanup (); for(i=0;i20;i+) signal(i,cleanup); shmid=shmget(shmkey,16*k,0777|ipc_creat); /*建立 16k 共享區 shmkey */ addr=shmat

16、(shmid,0,0);/* 掛接,并得到共享區首地址*/ printf (addr 0 x%xn,addr); pint=(char *)addr; for (i=a;i=e;i+) *pint+=i; pause();/*等待接收進程讀*/ cleanup() shmctl(shmid,ipc_rmid,0); exit (); #include #include #include #define shmkey 208 /*在實際實驗過程中, 為了避免每個同學建立的共享存儲區關鍵字一樣而相互干擾,關鍵字請用學號末3 位*/ #define k 1024 int shmid; main () int i; char *pint; char *addr; extern char * shmat (); shmid=shmget(shmkey,8*k,0777);/*取共享區shmkey的 id */ addr=shmat(shmid,0,0);/* 連接共享區 */ pint=(char *)addr; for (i=0;i5;i+) printf(%cn,-32+*pint+);/*打印共享區中的內容*/ 結果無法

溫馨提示

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

評論

0/150

提交評論