【linux】共享內存!!

在system V IPC裏面,共享內存是所有進程間通信速度最快的。因爲在消息隊列裏面,在消息傳遞的時候需要進行兩次拷貝(將數據拷貝到隊列節點裏面,從隊列節點裏面拷貝到內存)。
基本原理:
這裏寫圖片描述
注:進程間通訊的本質就是將不同的進程看到同一塊地址空間。但是在頁表的映射下,不同的進程所佔有的實際地址空間是不同的,所以在不同的進程裏面數據是相對獨立的。但是要是有一塊不同進程都可以訪問的空間,那麼就可以實現進程間通訊。這裏的共享內存就是不同進程都可以進行訪問的內存。

共享內存的缺點:共享內存沒有同步和互斥機制,但是可以銅價信號量的方法實現加鎖。

int shmget(key_t key,size_t size,int shmflag); //創建共享內存

key:共享內存的名稱編號
size:共享內存的大小
shmflag:模式標誌位(IPC_CREAT 、IPC_EXCL);
注:開闢的size通常爲一塊的整數倍(n*4K),但是用戶只能使用自己所開闢的大小內存
模式標誌位裏面,當同時使用IPC_CREAT|IPC_EXCL時候,當不存在共享內存的時候創建,當存在的時候報錯,單獨使用IPC_CREAT的時候不存在的時候創建,存在時候返回,單獨使用IPC_EXCL無任何意義。

void*  shmat(int shmid,const void * shmadd,int fshmlag);//將共享內存連接到進程地址空間

shmid:共享內存編號
shmadd:指定連接地址
shmflag:模式標誌位(SHM_RND、SHM_RDONLY)

int shmdt(const void * addr);//取消共享內存連接
int  shmctl(int shmid,int cmd,struct shmid_ds *buf);//控制共享內存

cmd:需要採取的動作
注:IPC_RMID:刪除共享內存

實例:實現不同進程的通信
comm.c

#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#define PATHNAME "/tmp"
#define PROJE_ID 0x6666

static int commshm(int flag){
    int _key = ftok(PATHNAME,PROJE_ID);
    int shmid;
    if(_key < 0){
        perror("fyok");
        return -1;
    }
    shmid = shmget(_key,4096,flag);
    if(shmid < 0){
        perror("shmget");
        return -2;
    }
    return shmid;
}

int Greatshmid(){
    return commshm(IPC_CREAT|IPC_EXCL|0666);
}

int Getshmid(){
    return commshm(IPC_CREAT);
}

int Destoryshm(int shmid){
    if(shmctl(shmid,IPC_RMID,NULL) < 0){
        perror("shmctl");
        return -1;
    }
    return 0;
}

#endif

comm.h

#ifndef _COMM_H__
#define _COMM_H__

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>

#define PATHNAME "."
#define PROJE_ID 0x12345

int commshm(int flag);
int Greatshmid();
int Getshmid();
int Destoryshm(int shmid);

#endif

server.c

#include"comm.h"


int main(){
    int shmid =  Greatshmid();

    int i = 100;
    char* addr = shmat(shmid,NULL,0);
    if(NULL == addr){
        perror("shmst");
        return -1;
    }
    while(i--){
        printf("client is say:%s\n",addr);
        sleep(1);
    }
    sleep(1);
    shmdt(addr);
    Destoryshm(shmid);
    return 0;
}

client.c

nclude"comm.h"


int main(){
    int shmid = Getshmid();
    int i = 0;
    char* addr = shmat(shmid,NULL,0);
    if(NULL == addr){
        perror("shmat");
        return -1;
    }
    while(i < 10){
        addr[i] = 'A'+i;
        i++;
        addr[i] = 0;
        sleep(1);
    }
    sleep(1);
    shmdt(addr);
    Destoryshm(shmid);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章