国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統(tǒng) > 正文

深入理解進程間通信之共享內存

2024-06-28 13:19:44
字體:
來源:轉載
供稿:網(wǎng)友
深入理解進程間通信之共享內存

  共享內存可以說是最有用的進程間通信方式,也是最快的ipC形式。是針對其他通信機制運行效率較低而設計的。兩個不同進程A、B共享內存的意思是,同一塊物理內存被映射到進程A、B各自的進程地址空間。進程A可以即時看到進程B對共享內存中數(shù)據(jù)的更新,反之亦然。由于多個進程共享同一塊內存區(qū)域,必然需要某種同步機制,互斥鎖和信號量都可以。

  采用共享內存通信的一個顯而易見的好處是效率高,因為進程可以直接讀寫內存,而不需要任何數(shù)據(jù)的拷貝。對于像管道和消息隊列等通信方式,則需要在內核和用戶空間進行四次的數(shù)據(jù)拷貝,而共享內存則只拷貝兩次數(shù)據(jù)[1]:一次從輸入文件到共享內存區(qū),另一次從共享內存區(qū)到輸出文件。實際上,進程之間在共享內存時,并不總是讀寫少量數(shù)據(jù)后就解除映射,有新的通信時,再重新建立共享內存區(qū)域。而是保持共享區(qū)域,直到通信完畢為止,這樣,數(shù)據(jù)內容一直保存在共享內存中,并沒有寫回文件。共享內存中的內容往往是在解除映射時才寫回文件的。因此,采用共享內存的通信方式效率是非常高的。

系統(tǒng)V共享內存原理

  進程間需要共享的數(shù)據(jù)被放在一個叫做IPC共享內存區(qū)域的地方,所有需要訪問該共享區(qū)域的進程都要把該共享區(qū)域映射到本進程的地址空間中去。系統(tǒng)V共享內存通過shmget獲得或創(chuàng)建一個IPC共享內存區(qū)域,并返回相應的標識符。內核在保證shmget獲得或創(chuàng)建一個共享內存區(qū),初始化該共享內存區(qū)相應的shmid_kernel結構體的同時,還將在特殊文件系統(tǒng)shm中,創(chuàng)建并打開一個同名文件,并在內存中建立起該文件的相應dentry及inode結構,新打開的文件不屬于任何一個進程(任何進程都可以訪問該共享內存區(qū))。所有這一切都是系統(tǒng)調用shmget完成的。

注:每一個共享內存區(qū)都有一個控制結構struct shmid_kernel,shmid_kernel是共享內存區(qū)域中非常重要的一個數(shù)據(jù)結構,它是存儲管理和文件系統(tǒng)結合起來的橋梁,定義如下:

struct shmid_kernel /* PRivate to the kernel */{        struct kern_ipc_perm shm_perm; /* Operation permission structure */    struct file *shm_file; /* pointer in kernel */    unsigned long shm_nattch; /* number of current attaches */    unsigned long shm_segsz; /* size of segment in bytes */    time_t shm_atim; /* last-attach time */    time_t shm_dtim; /* last-detach time */    time_t shm_ctim; /* last-change time */    pid_t shm_cprid; /* pid of creator */    pid_t shm_lprid; /* pid of last shmop() */};

  

  正如消息隊列和信號燈一樣,內核通過數(shù)據(jù)結構struct ipc_ids shm_ids維護系統(tǒng)中的所有共享內存區(qū)域。上圖中的shm_ids.entries變量指向一個ipc_id結構數(shù)組,而每個ipc_id結構數(shù)組中有個指向kern_ipc_perm結構的指針。到這里讀者應該很熟悉了,對于系統(tǒng)V共享內存區(qū)來說,kern_ipc_perm的宿主是 shmid_kernel結構,shmid_kernel是用來描述一個共享內存區(qū)域的,這樣內核就能夠控制系統(tǒng)中所有的共享區(qū)域。同時,在 shmid_kernel結構的file類型指針shm_file指向文件系統(tǒng)shm中相應的文件,這樣,共享內存區(qū)域就與shm文件系統(tǒng)中的文件對應起來。

  在創(chuàng)建了一個共享內存區(qū)域后,還要將它映射到進程地址空間,系統(tǒng)調用shmat()完成此項功能。由于在調用shmget()時,已經(jīng)創(chuàng)建了文件系統(tǒng) shm中的一個同名文件與共享內存區(qū)域相對應,因此,調用shmat()的過程相當于映射文件系統(tǒng)shm中的同名文件過程,原理與mmap()大同小異。

系統(tǒng)V共享內存API
  頭文件:    #include <sys/ipc.h>    #include <sys/shm.h>

  shmget()用來獲得共享內存區(qū)域的ID,如果不存在指定的共享區(qū)域就創(chuàng)建相應的區(qū)域。shmat()把共享內存區(qū)域映射到調用進程的地址空間中去,這樣,進程就可以方便地對共享區(qū)域進行訪問操作。shmdt()調用用來解除進程對共享內存區(qū)域的映射。shmctl實現(xiàn)對共享內存區(qū)域的控制操作。

系統(tǒng)V共享內存限制

  在/proc/sys/kernel/目錄下,記錄著系統(tǒng)V共享內存的一下限制,如一個共享內存區(qū)的最大字節(jié)數(shù)shmmax,系統(tǒng)范圍內最大共享內存區(qū)標識符數(shù)shmmni等,可以手工對其調整,但不推薦這樣做。

系統(tǒng)V共享內存范例
/***** testwrite.c *******/#include <sys/ipc.h>#include <sys/shm.h>#include <sys/types.h>#include <unistd.h>typedef struct{    char name[4];    int age;} people;main(int argc, char** argv){    int shm_id,i;    key_t key;    char temp;    people *p_map;    char* name = "/dev/shm/myshm2";    key = ftok(name,0);    if(key==-1)        perror("ftok error");    shm_id=shmget(key,4096,IPC_CREAT);        if(shm_id==-1)    {        perror("shmget error");        return;    }    p_map=(people*)shmat(shm_id,NULL,0);    temp='a';    for(i = 0;i<10;i++)    {        temp+=1;        memcpy((*(p_map+i)).name,&temp,1);        (*(p_map+i)).age=20+i;    }    if(shmdt(p_map)==-1)        perror(" detach error ");}/********** testread.c ************/#include <sys/ipc.h>#include <sys/shm.h>#include <sys/types.h>#include <unistd.h>typedef struct{    char name[4];    int age;} people;main(int argc, char** argv){    int shm_id,i;    key_t key;    people *p_map;    char* name = "/dev/shm/myshm2";    key = ftok(name,0);    if(key == -1)        perror("ftok error");    shm_id = shmget(key,4096,IPC_CREAT);        if(shm_id == -1)    {        perror("shmget error");        return;    }    p_map = (people*)shmat(shm_id,NULL,0);    for(i = 0;i<10;i++)    {    printf( "name:%s/n",(*(p_map+i)).name );    printf( "age %d/n",(*(p_map+i)).age );    }    if(shmdt(p_map) == -1)        perror(" detach error ");}
View Code

  


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 赤水市| 平阴县| 洛扎县| 贵州省| 南宁市| 葵青区| 兖州市| 巴林右旗| 武夷山市| 三门峡市| 高青县| 揭东县| 封丘县| 九江市| 长寿区| 临江市| 民和| 綦江县| 鹰潭市| 黑水县| 七台河市| 易门县| 金秀| 乌拉特中旗| 财经| 南通市| 安徽省| 灵宝市| 蓝山县| 中方县| 璧山县| 北海市| 荣成市| 额尔古纳市| 黑龙江省| 临夏市| 黑河市| 阿鲁科尔沁旗| 屏东市| 荃湾区| 大关县|