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

首頁 > 學院 > 開發(fā)設計 > 正文

進程間通信——共享內存

2019-11-08 01:53:13
字體:
來源:轉載
供稿:網友

前言


進程間ipC通信的三大主題,消息隊列,信號量,共享內存,我們接下來說一說共享內存,共享內存可以提供給服務器進程和客戶進程之間進行通信,不需要進行數(shù)據(jù)的復制,所以速度最快,只需要讓兩個進程通過頁表映射到同一塊物理內存即可,這樣,這塊物理內存是兩個進程都能看到的,這樣當一個進程進行寫操作,另外的一個進程也就可以做讀操作。所以問題關鍵也就是給出一個特定的存儲區(qū)。通常情況下,我們需要確保一個進程在寫的時候,另外一個進程不能去讀,所以我們可以使用信號量進行共享內存訪問。

這里寫圖片描述

這里寫圖片描述

創(chuàng)建共享內存


首先我們利用ftok函數(shù)生成key標識。

key_t ftok(const char *pathname, int PRoj_id);

然后我們使用shmget函數(shù),這個函數(shù)可以進行創(chuàng)建共享內存。

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

在這你要看好,這個size是需要進行申請的共享內存的大小,需要注意的是,操作系統(tǒng)為你提供的時候是按照頁來提供的,因為是按照頁提供的,所以size為4k的整數(shù)倍,然后shmflg和信號量以及消息隊列的類似,如果要創(chuàng)建新的共享內存,那么就是使用IPC_CREATE,IPC_EXCL。如果是已存在的,那么只需要使用IPC_CREATE或者傳0。

掛接共享內存


創(chuàng)建好共享的內存以后,這個時候我們就應該考慮的是讓進程去掛接共享內存。

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

掛接共享內存,shmflg一般表示什么方式進行掛接,一般都是取0,shmid是掛接的進程號。這個函數(shù)返回的是一個地址,我們可以想一下使用malloc的時候如何使用的,這個和那個類似。

去關聯(lián)共享內存


當一個進程不需要共享內存的時候,這個時候就需要去關聯(lián),

int shmdt(const void *shmaddr);

這個參數(shù)就是我們掛接以后返回的地址。

銷毀共享內存


我們可以使用函數(shù)銷毀共享內存,

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

上面的這個函數(shù)用來控制共享內存的操作,我們可以用它來刪除共享內存,當cmd取IPC_RMID的時候就可以刪除共享內存,另外我們也可以使用命令來進行操作ipcrm -m xxx 這樣也可以進行銷毀共享內存。

注意點


共享內存并沒有提供互斥和同步機制,所以一般都是我們自己來做這個,可以使用信號量保證互斥,共享內存一般來提供對大塊內存區(qū)域的訪問,因為共享內存不想IPC另外兩個一樣需要拷貝和搬遷,所以共享內存是最快的,所以使用也比較多。

對于一個共享內存,實現(xiàn)也應用了引用計數(shù)的原理,當進程脫離了共享內存區(qū)之后,計數(shù)器會減一,只有當計數(shù)器變?yōu)?的時候,就是沒有任何進程來使用這個共享內存區(qū),這個時候共享內存才會被刪除,當一個進程終止的時候,它所附加的共享內存區(qū)都會自動脫離。

實例


下面的例子是服務器進程進行創(chuàng)建共享共享內存,然后掛接,客戶進程是得到關聯(lián)共享內存,然后客戶進程一秒發(fā)一個a,這個時候服務器進程接受到,打印,從而實現(xiàn)共享內存。

comm.h

#ifndef __COMM_H_#define __COMM_H_#include<stdio.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#define PATHNAME "."#define PROJID 0x6666#define SIZE 4096*1int Comm_Shm(int flags);int Create_Shm();int Get_Shm();int Destory_Shm(int shmid);char *At_Shm(int shmid);int Dt_Shm(char *mem_addr);#endif //!__COMM_H_

comm.c

#include"comm.h"int Comm_Shm(int flags){ key_t shmkey=ftok(PATHNAME,PROJID); if(shmkey<0) { perror("ftok"); return -1; } printf("sda"); int shmid=shmget(shmkey,SIZE,flags); if(shmget<0) { perror("shmget"); return -2; } printf("create"); return shmid;}int Create_Shm(){ return Comm_Shm(IPC_CREAT|IPC_EXCL|0666);}int Get_Shm(){ return Comm_Shm(0);}int Destory_Shm(int shmid){ int ret=shmctl(shmid,IPC_RMID,NULL); if(ret<0) { perror("shmctl"); return -1; } return 0;}char* At_Shm(int shmid){ char *shm=(char *)shmat(shmid,NULL,0); return shm;}int Dt_Shm(char *mem_addr){ int ret =shmdt(mem_addr); return 0;}

client.c

#include"comm.h"int main(){ int shmid=Get_Shm(); char *add=At_Shm(shmid); printf("physic address:%s",add); int i=0; while(1) { sleep(1); add[i++] = 'a'; i %= (SIZE-1); add[i]='/0'; } Dt_Shm(add); return 0;}

server.c

#include"comm.h"int main(){ int shmid=Create_Shm(); sleep(5); char *add=At_Shm(shmid); while(1) { sleep(1); printf("%s/n",add); } sleep(5); Dt_Shm(add); Destory_Shm(shmid); return 0;}
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 嘉峪关市| 泾川县| 正镶白旗| 元谋县| 麻阳| 千阳县| 五指山市| 兴城市| 乌海市| 抚远县| 高青县| 横峰县| 麟游县| 上虞市| 南川市| 连城县| 深泽县| 嘉定区| 噶尔县| 阿城市| 庆阳市| 迁西县| 阜新市| 龙胜| 江北区| 水城县| 曲水县| 龙泉市| 罗城| 兰州市| 法库县| 大城县| 财经| 萨嘎县| 额济纳旗| 师宗县| 肥乡县| 吉木乃县| 林芝县| 德清县| 廉江市|