linux內存共享_第1頁
linux內存共享_第2頁
linux內存共享_第3頁
linux內存共享_第4頁
linux內存共享_第5頁
已閱讀5頁,還剩3頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、一、什么是共享內存顧名思義,共享內存就是允許兩個不相關的進程訪問同一個邏輯內存。共享內存是在兩個正在運行的進程之間共享和傳遞數(shù)據(jù)的一種非常有效的方式。不同進程之間共享的內存通常安排為同一段物理內存。進程可以將同一段共享內存連接到它們自己的地址空間中,所有進程都可以訪問共享內存中的地址,就好像它們是由用C語言函數(shù)malloc分配的內存一樣。而如果某個進程向共享內存寫入數(shù)據(jù),所做的改動將立即影響到可以訪問同一段共享內存的任何其他進程。特別提醒:共享內存并未提供同步機制,也就是說,在第一個進程結束對共享內存的寫操作之前,并無自動機制可以阻止第二個進程開始對它進行讀取。所以我們通常需要用其他的機制來同

2、步對共享內存的訪問,例如前面說到的信號量。有關信號量的更多內容,可以查閱我的另一篇文章:Linux進程間通信使用信號量二、共享內存的使得與信號量一樣,在Linux中也提供了一組函數(shù)接口用于使用共享內存,而且使用共享共存的接口還與信號量的非常相似,而且比使用信號量的接口來得簡單。它們聲明在頭文件 sys/shm.h中。1、shmget函數(shù)該函數(shù)用來創(chuàng)建共享內存,它的原型為:cpp view plaincopyprint?1. int shmget(key_t key, size_t size, int shmflg);

3、0; 第一個參數(shù),與信號量的semget函數(shù)一樣,程序需要提供一個參數(shù)key(非0整數(shù)),它有效地為共享內存段命名,shmget函數(shù)成功時返回一個與key相關的共享內存標識符(非負整數(shù)),用于后續(xù)的共享內存函數(shù)。調用失敗返回-1.不相關的進程可以通過該函數(shù)的返回值訪問同一共享內存,它代表程序可能要使用的某個資源,程序對所有共享內存的訪問都是間接的,程序先通過調用shmget函數(shù)并提供一個鍵,再由系統(tǒng)生成一個相應的共享內存標識符(shmget函數(shù)的返回值),只有shmget函數(shù)才直接使用信號量鍵,所有其他的信號量函數(shù)使用由semget函數(shù)返回的信號量標識符。第二個參數(shù),size以字節(jié)為

4、單位指定需要共享的內存容量第三個參數(shù),shmflg是權限標志,它的作用與open函數(shù)的mode參數(shù)一樣,如果要想在key標識的共享內存不存在時,創(chuàng)建它的話,可以與IPC_CREAT做或操作。共享內存的權限標志與文件的讀寫權限一樣,舉例來說,0644,它表示允許一個進程創(chuàng)建的共享內存被內存創(chuàng)建者所擁有的進程向共享內存讀取和寫入數(shù)據(jù),同時其他用戶創(chuàng)建的進程只能讀取共享內存。2、shmat函數(shù)第一次創(chuàng)建完共享內存時,它還不能被任何進程訪問,shmat函數(shù)的作用就是用來啟動對該共享內存的訪問,并把共享內存連接到當前進程的地址空間。它的原型如下:cpp view plaincopyprint?

5、1. void *shmat(int shm_id, const void *shm_addr, int shmflg);  第一個參數(shù),shm_id是由shmget函數(shù)返回的共享內存標識。第二個參數(shù),shm_addr指定共享內存連接到當前進程中的地址位置,通常為空,表示讓系統(tǒng)來選擇共享內存的地址。第三個參數(shù),shm_flg是一組標志位,通常為0。調用成功時返回一個指向共享內存第一個字節(jié)的指針,如果調用失敗返回-1.3、shmdt函數(shù)該函數(shù)用于將共享內存從當前進程中分離。注意,將共享內存分離并不是刪除它,

6、只是使該共享內存對當前進程不再可用。它的原型如下:cpp view plaincopyprint?1. int shmdt(const void *shmaddr);  參數(shù)shmaddr是shmat函數(shù)返回的地址指針,調用成功時返回0,失敗時返回-1.4、shmctl函數(shù)與信號量的semctl函數(shù)一樣,用來控制共享內存,它的原型如下:cpp view plaincopyprint?1. int shmctl(int shm_id, int command, struct&#

7、160;shmid_ds *buf);  第一個參數(shù),shm_id是shmget函數(shù)返回的共享內存標識符。第二個參數(shù),command是要采取的操作,它可以取下面的三個值 :    IPC_STAT:把shmid_ds結構中的數(shù)據(jù)設置為共享內存的當前關聯(lián)值,即用共享內存的當前關聯(lián)值覆蓋shmid_ds的值。    IPC_SET:如果進程有足夠的權限,就把共享內存的當前關聯(lián)值設置為shmid_ds結構中給出的值    IPC_RMID:刪除共享內存段第三個參數(shù),buf是一個結構指針,它指向共享內存模式和訪問

8、權限的結構。shmid_ds結構至少包括以下成員: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; 三、使用共享內存進行進程間通信說了這么多,又到了實戰(zhàn)的時候了。下面就以兩個不相關的進程來說明進程間如何通過共享內存來進行通信。其中一個文件shmread.c創(chuàng)建共享內存,并讀取其中的信息,另一個文件shmwrite.c向共享內存中寫入數(shù)據(jù)。為了方便操作和數(shù)據(jù)結構的統(tǒng)一,為這兩個文件定義了相同的數(shù)據(jù)結構,定義在文件shmdata.c中。結構shared_use_st中的written作為一個可讀或可寫的標志,非0:表示可讀,0表示可寫,text則是內存中的文件。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;/作為一個標志,非0:表示可讀,0表示可寫  9.   

11、  char textTEXT_SZ;/記錄寫入和讀取的文本  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ù)運行的標志  10.     void *shm = NULL;/分配的共享內存

13、的原始首地址  11.     struct shared_use_st *shared;/指向shm  12.     int shmid;/共享內存標識符  13.     /創(chuàng)建共享內存  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.     /將共享內存連接到當前進程的地址空間  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.     /設置共享內存  29.     shared = (struct shared_use_st*)shm;  30.     shared->written = 0

18、;  31.     while(running)/讀取共享內存中的數(shù)據(jù)  32.       33.         /沒有進程向共享內存定數(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ù),設置written使共享內存段可寫  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/有其他進程在寫數(shù)據(jù),不能讀取數(shù)據(jù)  45.             sleep(1)

23、;  46.       47.     /把共享內存從當前進程中分離  48.     if(shmdt(shm) = -1)  49.       50.         fprintf(stderr, "shmdt

24、 failedn");  51.         exit(EXIT_FAILURE);  52.       53.     /刪除共享內存  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)建共享內存  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.     /將共享內存連接到當前進程的地址空間  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.     /設置共享內存  31.     shared = (struct shared_use_st*)shm;

33、60; 32.     while(running)/向共享內存中寫數(shù)據(jù)  33.       34.         /數(shù)據(jù)還沒有被讀取,則等待數(shù)據(jù)被讀取,不能向共享內存中寫入文本  35.         while(shared->written = 1)&

34、#160; 36.           37.             sleep(1);  38.             printf("Waiting.n");  39.  

35、         40.         /向共享內存中寫入數(shù)據(jù)  41.         printf("Enter some text: ");  42.         fg

36、ets(buffer, BUFSIZ, stdin);  43.         strncpy(shared->text, buffer, TEXT_SZ);  44.         /寫完數(shù)據(jù),設置written使共享內存段可讀  45.        &#

37、160;shared->written = 1;  46.         /輸入了end,退出循環(huán)(程序)  47.         if(strncmp(buffer, "end", 3) = 0)  48.       

38、0;     running = 0;  49.       50.     /把共享內存從當前進程中分離  51.     if(shmdt(shm) = -1)  52.       53.         fprintf(stderr, "shmdt failedn

溫馨提示

  • 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

提交評論