進程間通信-------共享空間

        共享內存:使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。是針對其他通信機制運⾏效率較低⽽設計的。往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。共享內存效率高,因爲不像管道以及消息隊列一樣,讀寫時進行拷貝兩次,而共享內存直接進行內存讀寫,不需要進行拷貝。共享內存申請的空間內存在堆棧之間。生命週期爲隨內核。

       32位平臺下一個進程認爲自己的地址空間爲4G0~3G爲用戶區,3~4G爲內核區。

在驗證共享內存中我們會涉及到一些函數,下面對這些函數進行一一解釋:

1、申請共享內存——shmget()函數

   函數原型:int shmget(key_t key,size_t size,int shmflg);

   第一個參數,程序需要提供一個參數key,有效的爲共享內存段命名,key_t key=ftok(PATHNAME,PROJ_ID);

第二個參數:申請共享內存的大小,以字節爲單位。(一般是4096的整數倍)

第三個參數:權限標誌,IPC_CREAT|IPC_EXCL:若共享內存存在便出錯返回,若不存在則創建之,IPC_CREAT:若共享內存存在便打開返回,若不存在則創建之。

返回值:返回用戶可使用的共享內存標誌符。

2、釋放共享內存——shmctl()函數

   函數原型:int shmctl(int shmid,int cmd,struct shmid_ds *buf);

   第一個參數:shmget函數返回的共享內存標識符

   第二個參數:要使用的操作,此處爲IPC_RMID,表示刪除。

   第三個參數:buf對應的結構指針:

   struct shmid_ds

   {

      uid_t shm_perm.uid;

      uid_t shm_perm.gid;

      mode_t shm_perm.mode;

   };

 3、將共享內存掛接到進程的地址空間——shmat()函數

函數原型:void* shmat(int shmid,const void* shmaddr,int shmflg)

第二個參數:一般爲空。

第三個參數:一般爲0

 

 4、去關聯——shmdt()函數

函數原型:int shmdt(const void* shmaddr);

參數:   shmat()函數的返回值。

源碼驗證:

comm.h:

 #ifndef _COMM_H_
#define _COMM_H_
#include<stdio.h>
#include<unistd.h>
#include<error.h>
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#define PATHNAME "."
#define PROJ_ID 0x666

//創建共享內存
int create_shm(size_t size);

int comm_shm(size_t size,int shm_flag);

//銷燬
int destroy_shm(int shmid);

//獲取
int get_shm();
#endif


comm.c:

#include"comm.h"
int comm_shm(size_t size,int shm_flag)
{
key_t key=ftok(PATHNAME,PROJ_ID);
if(key<0)
{
perror("ftok");
return -1;
}
int shmid=shmget(key,size,shm_flag);
if(shmid<0)
{
perror("shmget");
return -2;
}
return shmid;
}
int create_shm(size_t size)
{
return comm_shm(size,IPC_CREAT|IPC_EXCL|0666);
}
int get_shm()
{
return comm_shm(0,IPC_CREAT);
}
int destroy_shm(int shmid)
{
    if(shmctl(shmid,IPC_RMID,NULL)<0)
{
perror("shmctl");
return -1;
}
return 0;
}

server.c:

#include"comm.h"
int main()
{
int shmid=create_shm(4096);
char *buf=shmat(shmid,NULL,0);
int count=0;
while(count<4096)
{
buf[count]='A'+count%26;
count++;
sleep(3);
buf[count]=0;
}
shmdt(buf);
destroy_shm(shmid);
return 0;
}

 client.c:

#include"comm.h"
int main()
{
int shmid=get_shm();
char* buf=shmat(shmid,NULL,0);
while(1)
{
printf("%s\n",buf);
sleep(3);
}
shmdt(buf);
return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章