青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉,開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

????????共享內存區域是被多個進程共享的一部分物理內存。如果多個進程都把該內存區域映射到自己的虛擬地址空間,則這些進程就都可以直接訪問該共享內存區域,從而可以通過該區域進行通信。共享內存是進程間共享數據的一種最快的方法,一個進程向共享內存區域寫入了數據,共享這個內存區域的所有進程就可以立刻看到其中的內容。這塊共享虛擬內存的頁面,出現在每一個共享該頁面的進程的頁表中。但是它不需要在所有進程的虛擬內存中都有相同的虛擬地址。
?
?
圖 共享內存映射圖??
?????????????????????????

?????????象所有的 System V IPC對象一樣,對于共享內存對象的獲取是由key控制。內存共享之后,對進程如何使用這塊內存就不再做檢查。它們必須依賴于其它機制,比如System V的信號燈來同步對于共享內存區域的訪問(信號燈如何控制對臨界代碼的訪問另起一篇說話)。
?
????????每一個新創建的共享內存對象都用一個shmid_kernel數據結構來表達。系統中所有的shmid_kernel數據結構都保存在shm_segs向量表中,該向量表的每一個元素都是一個指向shmid_kernel數據結構的指針。
shm_segs向量表的定義如下:
struct shmid_kernel *shm_segs[SHMMNI];

?
??? SHMMNI為128,表示系統中最多可以有128個共享內存對象。
?
??? 數據結構shmid_kernel的定義如下:
????struct shmid_kernel
????{????
????????struct shmid_ds u;???????? /* the following are private */
????????unsigned long shm_npages;? /* size of segment (pages) */
????????unsigned long *shm_pages;? /* array of ptrs to frames -> SHMMAX */?
????????struct vm_area_struct *attaches;? /* descriptors for attaches */
????};

?
??? 其中:
????shm_pages代表該共享內存對象的所占據的內存頁面數組,數組里面的每個元素當然是每個內存頁面的起始地址.
??? shm_npages則是該共享內存對象占用內存頁面的個數,以頁為單位。這個數量當然涵蓋了申請空間的最小整數倍.
????(A new shared memory segment,? with size? equal to the value of size rounded up to a multiple of PAGE_SIZE)
??? shmid_ds是一個數據結構,它描述了這個共享內存區的認證信息,字節大小,最后一次粘附時間、分離時間、改變時間,創建該共享區域的進程,最后一次對它操作的進程,當前有多少個進程在使用它等信息。
????其定義如下:
????struct shmid_ds {
????????struct ipc_perm shm_perm;?? /* operation perms */
????????int shm_segsz;????????????? /* size of segment (bytes) */
????????__kernel_time_t shm_atime;? /* last attach time */
????????__kernel_time_t shm_dtime;? /* last detach time */
????????__kernel_time_t shm_ctime;? /* last change time */
????????__kernel_ipc_pid_t shm_cpid; /* pid of creator */
????????__kernel_ipc_pid_t shm_lpid; /* pid of last operator */
????????unsigned short shm_nattch;?? /* no. of current attaches */
????????unsigned short shm_unused;?? /* compatibility */
????????void *shm_unused2;?????????? /* ditto - used by DIPC */
????????void *shm_unused3;?????????? /* unused */
????};

?
??????? attaches描述被共享的物理內存對象所映射的各進程的虛擬內存區域。每一個希望共享這塊內存的進程都必須通過系統調用將其關聯(attach)到它的虛擬內存中。這一過程將為該進程創建了一個新的描述這塊共享內存的vm_area_struct數據結構。創建時可以指定共享內存在它的虛擬地址空間的位置,也可以讓Linux自己為它選擇一塊足夠的空閑區域。
?
????????這個新的vm_area_struct結構是維系共享內存和使用它的進程之間的關系的,所以除了要關聯進程信息外,還要指明這個共享內存數據結構shmid_kernel所在位置; 另外,便于管理這些經常變化的vm_area_struct,所以采取了鏈表形式組織這些數據結構,鏈表由attaches指向,同時 vm_area_struct數據結構中專門提供了兩個指針:vm_next_shared和 vm_prev_shared,用于連接該共享區域在使用它的各進程中所對應的vm_area_struct數據結構。?

圖 System V IPC 機制 - 共享內存?

???????????? ??

????????Linux為共享內存提供了四種操作。
????????1. 共享內存對象的創建或獲得。與其它兩種IPC機制一樣,進程在使用共享內存區域以前,必須通過系統調用sys_ipc (call值為SHMGET)創建一個鍵值為key的共享內存對象,或獲得已經存在的鍵值為key的某共享內存對象的引用標識符。以后對共享內存對象的訪問都通過該引用標識符進行。對共享內存對象的創建或獲得由函數sys_shmget完成,其定義如下:
int sys_shmget (key_t key, int size, int shmflg)
?
??? 這里key是表示該共享內存對象的鍵值,size是該共享內存區域的大小(以字節為單位),shmflg是標志(對該共享內存對象的特殊要求)。
?
??? 它所做的工作如下:
??? 1) 如果key == IPC_PRIVATE,則總是會創建一個新的共享內存對象。
?但是? (The name choice IPC_PRIVATE was perhaps unfortunate, IPC_NEW would more?clearly show its function)
??? * 算出size要占用的頁數,檢查其合法性。
??? * 申請一塊內存用于建立shmid_kernel數據結構,注意這里申請的內存區域大小不包括真正的共享內存區,實際上,要等到第一個進程試圖訪問它的時候才真正創建共享內存區。
??? * 根據該共享內存區所占用的頁數,為其申請一塊空間用于建立頁表(每頁4個字節),將頁表清0。
??? * 搜索向量表shm_segs,為新創建的共享內存對象找一個空位置。
??? * 填寫shmid_kernel數據結構,將其加入到向量表shm_segs中為其找到的空位置。
??? * 返回該共享內存對象的引用標識符。
?
??? 2) 在向量表shm_segs中查找鍵值為key的共享內存對象,結果有三:
??? * 如果沒有找到,而且在操作標志shmflg中沒有指明要創建新共享內存,則錯誤返回,否則創建一個新的共享內存對象。
??? * 如果找到了,但該次操作要求必須創建一個鍵值為key的新對象,那么錯誤返回。
??? * 否則,合法性、認證檢查,如有錯,則錯誤返回;否則,返回該內存對象的引用標識符。
?
??? 共享內存對象的創建者可以控制對于這塊內存的訪問權限和它的key是公開還是私有。如果有足夠的權限,它也可以把共享內存鎖定在物理內存中。
??? 參見include/linux/shm.h
?
??? 2. 關聯。在創建或獲得某個共享內存區域的引用標識符后,還必須將共享內存區域映射(粘附)到進程的虛擬地址空間,然后才能使用該共享內存區域。系統調用 sys_ipc(call值為SHMAT)用于共享內存區到進程虛擬地址空間的映射,而真正完成粘附動作的是函數sys_shmat,
?
其定義如下:???

???????#include <sys/types.h>
?????? #include <sys/shm.h>

?????? void *shmat(int shmid, const void *shmaddr, int shmflg);


?
??? 其中:
???? shmid是shmget返回的共享內存對象的引用標識符;
??? shmaddr用來指定該共享內存區域在進程的虛擬地址空間對應的虛擬地址;
??? shmflg是映射標志;
????返回的是 在進程中的虛擬地址
?
??? 該函數所做的工作如下:
??? 1) 根據shmid找到共享內存對象。
??? 2) 如果shmaddr為0,即用戶沒有指定該共享內存區域在它的虛擬空間中的位置,則由系統在進程的虛擬地址空間中為其找一塊區域(從1G開始);否則,就用shmaddr作為映射的虛擬地址。
?? (If? shmaddr? is NULL, the system chooses a suitable (unused) address a他 which to attach the segment)
??? 3) 檢查虛擬地址的合法性(不能超過進程的最大虛擬空間大小—3G,不能太接近堆棧棧頂)。
??? 4) 認證檢查。
??? 5) 申請一塊內存用于建立數據結構vm_area_struct,填寫該結構。
??? 6) 檢查該內存區域,將其加入到進程的mm結構和該共享內存對象的vm_area_struct隊列中。
?
??? 共享內存的粘附只是創建一個vm_area_struct數據結構,并將其加入到相應的隊列中,此時并沒有創建真正的共享內存頁。
?
??? 當進程第一次訪問共享虛擬內存的某頁時,因為所有的共享內存頁還都沒有分配,所以會發生一個page fault異常。當Linux處理這個page fault的時候,它找到發生異常的虛擬地址所在的vm_area_struct數據結構。在該數據結構中包含有這類共享虛擬內存的一組處理程序,其中的 nopage操作用來處理虛擬頁對應的物理頁不存在的情況。對共享內存,該操作是shm_nopage(定義在ipc/shm.c中)。該操作在描述這個共享內存的shmid_kernel數據結構的頁表shm_pages中查找發生page fault異常的虛擬地址所對應的頁表條目,看共享頁是否存在(頁表條目為0,表示共享頁是第一次使用)。如果不存在,它就分配一個物理頁,并為它創建一個頁表條目。這個條目不但進入當前進程的頁表,同時也存到shmid_kernel數據結構的頁表shm_pages中。
?
??? 當下一個進程試圖訪問這塊內存并得到一個page fault的時候,經過同樣的路徑,也會走到函數shm_nopage。此時,該函數查看shmid_kernel數據結構的頁表shm_pages時,發現共享頁已經存在,它只需把這里的頁表項填到進程頁表的相應位置即可,而不需要重新創建物理頁。所以,是第一個訪問共享內存頁的進程使得這一頁被創建,而隨后訪問它的其它進程僅把此頁加到它們的虛擬地址空間。
?
??? 3. 分離。當進程不再需要共享虛擬內存的時候,它們與之分離(detach)。只要仍舊有其它進程在使用這塊內存,這種分離就只會影響當前的進程,而不會影響其它進程。當前進程的vm_area_struct數據結構被從shmid_ds中刪除,并被釋放。當前進程的頁表也被更新,共享內存對應的虛擬內存頁被標記為無效。當共享這塊內存的最后一個進程與之分離時,共享內存頁被釋放,同時,這塊共享內存的shmid_kernel數據結構也被釋放。
?
? 系統調用sys_ipc (call值為SHMDT) 用于共享內存區與進程虛擬地址空間的分離,而真正完成分離動作的是函數????

??? sys_shmdt,其定義如下:
??? int sys_shmdt (char *shmaddr)
?
??? 其中shmaddr是進程要分離的共享頁的開始虛擬地址。
?
??? 該函數搜索進程的內存結構中的所有vm_area_struct數據結構,找到地址shmaddr對應的一個,調用函數do_munmap將其釋放。
?
??? 在函數do_munmap中,將要釋放的vm_area_struct數據結構從進程的虛擬內存中摘下,清除它在進程頁表中對應的頁表項(可能占多個頁表項).?
??
??? 如果共享的虛擬內存沒有被鎖定在物理內存中,分離會更加復雜。因為在這種情況下,共享內存的頁可能在系統大量使用內存的時候被交換到系統的交換磁盤。為了避免這種情況,可以通過下面的控制操作,將某共享內存頁鎖定在物理內存不允許向外交換。共享內存的換出和換入,已在第3章中討論。
?
??? 4. 控制。Linux在共享內存上實現的第四種操作是共享內存的控制(call值為SHMCTL的sys_ipc調用),它由函數sys_shmctl實現。控制操作包括獲得共享內存對象的狀態,設置共享內存對象的參數(如uid、gid、mode、ctime等),將共享內存對象在內存中鎖定和釋放(在對象的mode上增加或去除SHM_LOCKED標志),釋放共享內存對象資源等。
?
??? 共享內存提供了一種快速靈活的機制,它允許進程之間直接共享大量的數據,而無須使用拷貝或系統調用。共享內存的主要局限性是它不能提供同步,如果兩個進程企圖修改相同的共享內存區域,由于內核不能串行化這些動作,因此寫的數據可能任意地互相混合。所以使用共享內存的進程必須設計它們自己的同步協議,如用信號燈等。

以下是使用共享內存機制進行進程間通信的基本操作:

需要包含的頭文件:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

1.創建共享內存:

?int shmget(key_t key,int size,int shmflg);

參數說明:

key:用來表示新建或者已經存在的共享內存去的關鍵字。

size:創建共享內存的大小。

shmflg:可以指定的特殊標志。IPC_CREATE,IPC_EXCL以及低九位的權限。

eg:

int shmid;

shmid=shmget(IPC_PRIVATE,4096,IPC_CREATE|IPC_EXCL|0660);

if(shmid==-1)

perror("shmget()");

?

2.連接共享內存

char *shmat(int shmid,char *shmaddr,int shmflg);

參數說明

shmid:共享內存的關鍵字

shmaddr:指定共享內存出現在進程內存地址的什么位置,通常我們讓內核自己決定一個合適的地址位置,用的時候設為0。

shmflg:制定特殊的標志位。

eg:

int shmid;

char *shmp;

shmp=shmat(shmid,0,0);

if(shmp==(char *)(-1))

perror("shmat()\n");

3.使用共享內存

在使用共享內存是需要注意的是,為防止內存訪問沖突,我們一般與信號量結合使用。

4.分離共享內存:當程序不再需要共享內后,我們需要將共享內存分離以便對其進行釋放,分離共享內存的函數原形如下:

int shmdt(char *shmaddr);


?

5. 釋放共享內存

int shmctl(int shmid,int cmd,struct shmid_ds *buf);

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品久久久久久久久久久久久久 | 狠色狠色综合久久| 欧美日韩国产系列| 欧美精品一区在线发布| 欧美日韩国产二区| 亚洲国产精品第一区二区| 亚洲国产精品一区二区三区| 久久精品成人| 女生裸体视频一区二区三区| 欧美国产在线观看| 亚洲精品系列| 亚洲一区二区三区在线播放| 亚洲曰本av电影| 欧美日韩亚洲另类| 国产亚洲精品久久久久婷婷瑜伽 | 亚洲激情在线观看| 91久久夜色精品国产九色| 亚洲激情视频网| 99在线精品观看| 久久精品国产免费看久久精品| 亚洲日韩欧美视频| 性欧美xxxx视频在线观看| 久久中文字幕一区二区三区| 欧美午夜久久| 一区二区三区无毛| 国产精品99久久久久久久女警| 久久天堂成人| 正在播放亚洲一区| 欧美黄色aa电影| 狠狠爱www人成狠狠爱综合网| 欧美在线3区| 亚洲伦伦在线| 欧美日韩亚洲综合| 久久riav二区三区| 亚洲乱码视频| 国产精品成人av性教育| 欧美综合激情网| 久久久久久夜| 国产日韩欧美在线视频观看| 99re8这里有精品热视频免费| 欧美一区视频在线| 欧美在线观看一区| 国产欧美精品va在线观看| 亚洲精品久久久久中文字幕欢迎你| 欧美亚洲综合在线| 亚洲精选中文字幕| 国产精品色在线| 亚洲午夜在线观看视频在线| 欧美激情在线狂野欧美精品| 欧美日本三区| 久久久999精品免费| 亚洲影院一区| 在线日本欧美| 欧美激情按摩在线| 国产精品美女一区二区| 亚洲在线视频免费观看| 日韩亚洲精品视频| 欧美精品二区三区四区免费看视频| 精品不卡一区| 日韩视频三区| 黄色欧美成人| 亚洲一区二区三区激情| 在线精品福利| 亚洲字幕在线观看| 国产欧美成人| 亚洲精品影视| 136国产福利精品导航| 亚洲理伦电影| 亚洲国产老妈| 欧美中文在线字幕| 欧美亚洲一区二区在线| 欧美黄色大片网站| 久久人人九九| 欧美成人免费观看| 中日韩美女免费视频网址在线观看 | 欧美激情中文不卡| 久久av在线| 欧美日韩成人综合天天影院| 麻豆成人在线播放| 久久久亚洲精品一区二区三区| 一卡二卡3卡四卡高清精品视频| 久久av二区| 久久爱另类一区二区小说| 国产精品v片在线观看不卡 | 欧美精品videossex性护士| 鲁鲁狠狠狠7777一区二区| 国产人成精品一区二区三| 中文久久乱码一区二区| 一区二区三区精品视频在线观看 | 欧美高清一区| 免费视频最近日韩| 欧美日韩高清在线播放| 欧美电影免费网站| 欧美日韩伦理在线| 亚洲国产高清在线| 国产精品视频999| 99成人在线| 在线观看欧美日韩国产| 一本久久a久久精品亚洲| 国产亚洲成av人片在线观看桃| 亚洲一区二区免费视频| 亚洲欧美日韩综合aⅴ视频| 久久亚洲私人国产精品va媚药| 一区二区免费在线视频| 欧美黄免费看| 一本一本a久久| 亚洲综合第一页| 国产欧美亚洲日本| 欧美专区在线观看一区| 麻豆av一区二区三区久久| 亚洲国产成人高清精品| 男人插女人欧美| 久久先锋资源| 亚洲国产精品va| 欧美成人一区二区在线| 亚洲精品久久久久久久久| 在线视频你懂得一区| 国产精品日韩在线观看| 欧美一区亚洲二区| 亚洲国产成人av在线| 亚洲伊人观看| 国产在线精品一区二区中文 | 国产精品稀缺呦系列在线| 性欧美精品高清| 欧美激情在线观看| 亚洲欧美日本视频在线观看| 免费短视频成人日韩| 久久噜噜噜精品国产亚洲综合| 亚洲高清在线播放| 欧美日韩喷水| 久久久久免费观看| 日韩亚洲视频| 久久一区精品| 亚洲男女自偷自拍| 欧美电影电视剧在线观看| 亚洲欧美日韩在线| 激情一区二区三区| 欧美日韩在线播| 久久免费少妇高潮久久精品99| 亚洲精品一区二区三区婷婷月| 欧美在线观看一区| 亚洲美女av电影| 蜜桃视频一区| 亚洲免费在线看| 亚洲黄网站黄| 久久亚裔精品欧美| 亚洲欧美精品在线| 在线免费观看一区二区三区| 国产精品国产三级国产aⅴ浪潮| 久久久夜精品| 亚洲综合大片69999| 亚洲国产日韩欧美| 亚洲免费电影在线观看| 国产一区二区精品久久91| 欧美日韩另类在线| 免费欧美视频| 久久婷婷蜜乳一本欲蜜臀| 亚洲综合色激情五月| 一区二区不卡在线视频 午夜欧美不卡在 | 乱人伦精品视频在线观看| 午夜精品区一区二区三| 亚洲精品一区二区在线| 免费永久网站黄欧美| 欧美一级日韩一级| 制服丝袜亚洲播放| 日韩视频中文字幕| 亚洲国产一区在线| 悠悠资源网亚洲青| 激情视频一区二区| 很黄很黄激情成人| 国产综合色在线| 国产日产亚洲精品| 国产日韩av高清| 国产色婷婷国产综合在线理论片a| 欧美日韩精品伦理作品在线免费观看| 男同欧美伦乱| 欧美电影免费网站| 欧美激情一区二区久久久| 免费在线观看精品| 欧美成人亚洲| 欧美日韩成人一区二区| 欧美区一区二区三区| 欧美日韩成人在线观看| 欧美日韩综合久久| 欧美一区二区成人| 亚洲国产高清aⅴ视频| 欧美国产视频在线| 亚洲国产高清自拍| 亚洲精品国产精品国自产观看浪潮| 亚洲国产精品视频| 亚洲精品乱码久久久久久蜜桃91 | 久久综合久久综合九色| 欧美1区免费| 亚洲电影在线播放| 亚洲激情另类| 在线亚洲欧美专区二区| 亚洲视频精品在线| 激情亚洲网站| 国产日韩欧美| 亚洲国产岛国毛片在线|