




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、一、什么是共享內(nèi)存顧名思義,共享內(nèi)存就是允許兩個(gè)不相關(guān)的進(jìn)程訪問(wèn)同一個(gè)邏輯內(nèi)存。共享內(nèi)存是在兩個(gè)正在運(yùn)行的進(jìn)程之間共享和傳遞數(shù)據(jù)的一種非常有效的方式。不同進(jìn)程之間共享的內(nèi)存通常安排為同一段物理內(nèi)存。進(jìn)程可以將同一段共享內(nèi)存連接到它們自己的地址空間中,所有進(jìn)程都可以訪問(wèn)共享內(nèi)存中的地址,就好像它們是由用C語(yǔ)言函數(shù)malloc分配的內(nèi)存一樣。而如果某個(gè)進(jìn)程向共享內(nèi)存寫(xiě)入數(shù)據(jù),所做的改動(dòng)將立即影響到可以訪問(wèn)同一段共享內(nèi)存的任何其他進(jìn)程。特別提醒:共享內(nèi)存并未提供同步機(jī)制,也就是說(shuō),在第一個(gè)進(jìn)程結(jié)束對(duì)共享內(nèi)存的寫(xiě)操作之前,并無(wú)自動(dòng)機(jī)制可以阻止第二個(gè)進(jìn)程開(kāi)始對(duì)它進(jìn)行讀取。所以我們通常需要用其他的機(jī)制來(lái)同
2、步對(duì)共享內(nèi)存的訪問(wèn),例如前面說(shuō)到的信號(hào)量。有關(guān)信號(hào)量的更多內(nèi)容,可以查閱我的另一篇文章:Linux進(jìn)程間通信使用信號(hào)量二、共享內(nèi)存的使得與信號(hào)量一樣,在Linux中也提供了一組函數(shù)接口用于使用共享內(nèi)存,而且使用共享共存的接口還與信號(hào)量的非常相似,而且比使用信號(hào)量的接口來(lái)得簡(jiǎn)單。它們聲明在頭文件 sys/shm.h中。1、shmget函數(shù)該函數(shù)用來(lái)創(chuàng)建共享內(nèi)存,它的原型為:cpp view plaincopyprint?1. int shmget(key_t key, size_t size, int shmflg);
3、0; 第一個(gè)參數(shù),與信號(hào)量的semget函數(shù)一樣,程序需要提供一個(gè)參數(shù)key(非0整數(shù)),它有效地為共享內(nèi)存段命名,shmget函數(shù)成功時(shí)返回一個(gè)與key相關(guān)的共享內(nèi)存標(biāo)識(shí)符(非負(fù)整數(shù)),用于后續(xù)的共享內(nèi)存函數(shù)。調(diào)用失敗返回-1.不相關(guān)的進(jìn)程可以通過(guò)該函數(shù)的返回值訪問(wèn)同一共享內(nèi)存,它代表程序可能要使用的某個(gè)資源,程序?qū)λ泄蚕韮?nèi)存的訪問(wèn)都是間接的,程序先通過(guò)調(diào)用shmget函數(shù)并提供一個(gè)鍵,再由系統(tǒng)生成一個(gè)相應(yīng)的共享內(nèi)存標(biāo)識(shí)符(shmget函數(shù)的返回值),只有shmget函數(shù)才直接使用信號(hào)量鍵,所有其他的信號(hào)量函數(shù)使用由semget函數(shù)返回的信號(hào)量標(biāo)識(shí)符。第二個(gè)參數(shù),size以字節(jié)為
4、單位指定需要共享的內(nèi)存容量第三個(gè)參數(shù),shmflg是權(quán)限標(biāo)志,它的作用與open函數(shù)的mode參數(shù)一樣,如果要想在key標(biāo)識(shí)的共享內(nèi)存不存在時(shí),創(chuàng)建它的話,可以與IPC_CREAT做或操作。共享內(nèi)存的權(quán)限標(biāo)志與文件的讀寫(xiě)權(quán)限一樣,舉例來(lái)說(shuō),0644,它表示允許一個(gè)進(jìn)程創(chuàng)建的共享內(nèi)存被內(nèi)存創(chuàng)建者所擁有的進(jìn)程向共享內(nèi)存讀取和寫(xiě)入數(shù)據(jù),同時(shí)其他用戶創(chuàng)建的進(jìn)程只能讀取共享內(nèi)存。2、shmat函數(shù)第一次創(chuàng)建完共享內(nèi)存時(shí),它還不能被任何進(jìn)程訪問(wèn),shmat函數(shù)的作用就是用來(lái)啟動(dòng)對(duì)該共享內(nèi)存的訪問(wèn),并把共享內(nèi)存連接到當(dāng)前進(jìn)程的地址空間。它的原型如下:cpp view plaincopyprint?
5、1. void *shmat(int shm_id, const void *shm_addr, int shmflg); 第一個(gè)參數(shù),shm_id是由shmget函數(shù)返回的共享內(nèi)存標(biāo)識(shí)。第二個(gè)參數(shù),shm_addr指定共享內(nèi)存連接到當(dāng)前進(jìn)程中的地址位置,通常為空,表示讓系統(tǒng)來(lái)選擇共享內(nèi)存的地址。第三個(gè)參數(shù),shm_flg是一組標(biāo)志位,通常為0。調(diào)用成功時(shí)返回一個(gè)指向共享內(nèi)存第一個(gè)字節(jié)的指針,如果調(diào)用失敗返回-1.3、shmdt函數(shù)該函數(shù)用于將共享內(nèi)存從當(dāng)前進(jìn)程中分離。注意,將共享內(nèi)存分離并不是刪除它,
6、只是使該共享內(nèi)存對(duì)當(dāng)前進(jìn)程不再可用。它的原型如下:cpp view plaincopyprint?1. int shmdt(const void *shmaddr); 參數(shù)shmaddr是shmat函數(shù)返回的地址指針,調(diào)用成功時(shí)返回0,失敗時(shí)返回-1.4、shmctl函數(shù)與信號(hào)量的semctl函數(shù)一樣,用來(lái)控制共享內(nèi)存,它的原型如下:cpp view plaincopyprint?1. int shmctl(int shm_id, int command, struct
7、160;shmid_ds *buf); 第一個(gè)參數(shù),shm_id是shmget函數(shù)返回的共享內(nèi)存標(biāo)識(shí)符。第二個(gè)參數(shù),command是要采取的操作,它可以取下面的三個(gè)值 : IPC_STAT:把shmid_ds結(jié)構(gòu)中的數(shù)據(jù)設(shè)置為共享內(nèi)存的當(dāng)前關(guān)聯(lián)值,即用共享內(nèi)存的當(dāng)前關(guān)聯(lián)值覆蓋shmid_ds的值。 IPC_SET:如果進(jìn)程有足夠的權(quán)限,就把共享內(nèi)存的當(dāng)前關(guān)聯(lián)值設(shè)置為shmid_ds結(jié)構(gòu)中給出的值 IPC_RMID:刪除共享內(nèi)存段第三個(gè)參數(shù),buf是一個(gè)結(jié)構(gòu)指針,它指向共享內(nèi)存模式和訪問(wèn)
8、權(quán)限的結(jié)構(gòu)。shmid_ds結(jié)構(gòu)至少包括以下成員:cpp view plaincopyprint?1. struct shmid_ds 2. 3. uid_t shm_perm.uid; 4. uid_t shm_perm.gid; 5. mode_t shm_perm.mode; 6. ;&
9、#160; 三、使用共享內(nèi)存進(jìn)行進(jìn)程間通信說(shuō)了這么多,又到了實(shí)戰(zhàn)的時(shí)候了。下面就以兩個(gè)不相關(guān)的進(jìn)程來(lái)說(shuō)明進(jìn)程間如何通過(guò)共享內(nèi)存來(lái)進(jìn)行通信。其中一個(gè)文件shmread.c創(chuàng)建共享內(nèi)存,并讀取其中的信息,另一個(gè)文件shmwrite.c向共享內(nèi)存中寫(xiě)入數(shù)據(jù)。為了方便操作和數(shù)據(jù)結(jié)構(gòu)的統(tǒng)一,為這兩個(gè)文件定義了相同的數(shù)據(jù)結(jié)構(gòu),定義在文件shmdata.c中。結(jié)構(gòu)shared_use_st中的written作為一個(gè)可讀或可寫(xiě)的標(biāo)志,非0:表示可讀,0表示可寫(xiě),text則是內(nèi)存中的文件。shmdata.h的源代碼如下:cpp view plaincopyprint?1. #ifndef
10、160;_SHMDATA_H_HEADER 2. #define _SHMDATA_H_HEADER 3. 4. #define TEXT_SZ 2048 5. 6. struct shared_use_st 7. 8. int written;/作為一個(gè)標(biāo)志,非0:表示可讀,0表示可寫(xiě) 9.
11、 char textTEXT_SZ;/記錄寫(xiě)入和讀取的文本 10. ; 11. 12. #endif 源文件shmread.c的源代碼如下:cpp view plaincopyprint?1. #include <unistd.h> 2. #include <stdlib.h> 3. #include <stdio.h> 4. #in
12、clude <sys/shm.h> 5. #include "shmdata.h" 6. 7. int main() 8. 9. int running = 1;/程序是否繼續(xù)運(yùn)行的標(biāo)志 10. void *shm = NULL;/分配的共享內(nèi)存
13、的原始首地址 11. struct shared_use_st *shared;/指向shm 12. int shmid;/共享內(nèi)存標(biāo)識(shí)符 13. /創(chuàng)建共享內(nèi)存 14. shmid = shmget(key_t)1234, sizeof(struct
14、0;shared_use_st), 0666|IPC_CREAT); 15. if(shmid = -1) 16. 17. fprintf(stderr, "shmget failedn"); 18.
15、; exit(EXIT_FAILURE); 19. 20. /將共享內(nèi)存連接到當(dāng)前進(jìn)程的地址空間 21. shm = shmat(shmid, 0, 0); 22. if(shm = (void*)-1)
16、0; 23. 24. fprintf(stderr, "shmat failedn"); 25. exit(EXIT_FAILURE); 26. 27.
17、160; printf("nMemory attached at %Xn", (int)shm); 28. /設(shè)置共享內(nèi)存 29. shared = (struct shared_use_st*)shm; 30. shared->written = 0
18、; 31. while(running)/讀取共享內(nèi)存中的數(shù)據(jù) 32. 33. /沒(méi)有進(jìn)程向共享內(nèi)存定數(shù)據(jù)有數(shù)據(jù)可讀取 34. if(shared->written != 0)
19、0;35. 36. printf("You wrote: %s", shared->text); 37. slee
20、p(rand() % 3); 38. /讀取完數(shù)據(jù),設(shè)置written使共享內(nèi)存段可寫(xiě) 39. shared->written = 0; 40.
21、60; /輸入了end,退出循環(huán)(程序) 41. if(strncmp(shared->text, "end", 3) = 0) 42.
22、60; running = 0; 43. 44. else/有其他進(jìn)程在寫(xiě)數(shù)據(jù),不能讀取數(shù)據(jù) 45. sleep(1)
23、; 46. 47. /把共享內(nèi)存從當(dāng)前進(jìn)程中分離 48. if(shmdt(shm) = -1) 49. 50. fprintf(stderr, "shmdt
24、 failedn"); 51. exit(EXIT_FAILURE); 52. 53. /刪除共享內(nèi)存 54. if(shmctl(shmid, IPC_RMID, 0) = -1) 55
25、. 56. fprintf(stderr, "shmctl(IPC_RMID) failedn"); 57. exit(EXIT_FAILURE); 58. 59. &
26、#160; exit(EXIT_SUCCESS); 60. 源文件shmwrite.c的源代碼如下:cpp view plaincopyprint?1. #include <unistd.h> 2. #include <stdlib.h> 3. #include <stdio.h> 4. #include <string.h> 5. #incl
27、ude <sys/shm.h> 6. #include "shmdata.h" 7. 8. int main() 9. 10. int running = 1; 11. void *shm = NULL; 12.
28、; struct shared_use_st *shared = NULL; 13. char bufferBUFSIZ + 1;/用于保存輸入的文本 14. int shmid; 15. /創(chuàng)建共享內(nèi)存 16.
29、160;shmid = shmget(key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT); 17. if(shmid = -1) 18. 19. fprintf(stderr, "shm
30、get failedn"); 20. exit(EXIT_FAILURE); 21. 22. /將共享內(nèi)存連接到當(dāng)前進(jìn)程的地址空間 23. shm = shmat(shmid, (void*)0, 0);
31、60; 24. if(shm = (void*)-1) 25. 26. fprintf(stderr, "shmat failedn"); 27. exit(EXIT_FAI
32、LURE); 28. 29. printf("Memory attached at %Xn", (int)shm); 30. /設(shè)置共享內(nèi)存 31. shared = (struct shared_use_st*)shm;
33、60; 32. while(running)/向共享內(nèi)存中寫(xiě)數(shù)據(jù) 33. 34. /數(shù)據(jù)還沒(méi)有被讀取,則等待數(shù)據(jù)被讀取,不能向共享內(nèi)存中寫(xiě)入文本 35. while(shared->written = 1)&
34、#160; 36. 37. sleep(1); 38. printf("Waiting.n"); 39.
35、 40. /向共享內(nèi)存中寫(xiě)入數(shù)據(jù) 41. printf("Enter some text: "); 42. fg
36、ets(buffer, BUFSIZ, stdin); 43. strncpy(shared->text, buffer, TEXT_SZ); 44. /寫(xiě)完數(shù)據(jù),設(shè)置written使共享內(nèi)存段可讀 45.
37、160;shared->written = 1; 46. /輸入了end,退出循環(huán)(程序) 47. if(strncmp(buffer, "end", 3) = 0) 48.
38、0; running = 0; 49. 50. /把共享內(nèi)存從當(dāng)前進(jìn)程中分離 51. if(shmdt(shm) = -1) 52. 53. fprintf(stderr, "shmdt failedn
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- JJF 2201-2025膠體金免疫層析分析儀校準(zhǔn)規(guī)范
- JJF 2197-2025頻標(biāo)比對(duì)器校準(zhǔn)規(guī)范
- 健身俱樂(lè)部合同范本
- 分成合同范本上樣
- 蝦皮合作合同范本
- 代家出租民房合同范本
- 企業(yè)股票承銷合同范本
- 加盟福田汽車合同范本
- 全新拖拉機(jī)買賣合同范本
- 獸藥欠賬銷售合同范本
- 2025年湘教版二年級(jí)美術(shù)下冊(cè)計(jì)劃與教案
- GB/T 4706.30-2024家用和類似用途電器的安全第30部分:廚房機(jī)械的特殊要求
- 2024年岳陽(yáng)職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(kù)及答案解析
- 消防安全管理制度完整版完整版
- 《朝天子詠喇叭》教學(xué)設(shè)計(jì)
- 《金融學(xué)基礎(chǔ)》實(shí)訓(xùn)手冊(cè)
- 稅收基礎(chǔ)知識(shí)考試題庫(kù)
- 1t燃?xì)庹羝仩t用戶需求(URS)(共13頁(yè))
- 廣發(fā)證券分支機(jī)構(gòu)人員招聘登記表
- 機(jī)電一體化系統(tǒng)設(shè)計(jì)課件姜培剛[1]
- 《質(zhì)量管理小組活動(dòng)準(zhǔn)則》2020版_20211228_111842
評(píng)論
0/150
提交評(píng)論