C语言进程间通信(四)——共享内存

共享内存通信方式效率最高,毕竟是直接操作内存,但是要保证多个进程对同一块内存访问的同步互斥比较麻烦,借助信号量实现

对每个共享存储段,内核维护一个shmid_ds类型的结构体,定义在<sys/shm.h>文件中

C代码 
struct shmid_ds  
{  
 struct ipc_perm shm_perm;   //共享内存的ipc_perm结构  
 size_t shm_segsz;   //共享内存区域大小,字节表示  
 pid_t shm_lpid; //最后一次调用shmop函数的进程ID  
 pid_t shm_cpid; //创建此共享内存的进程ID  
 unsigned short shm_lkcnt;   //共享内存被锁定的时间数  
 unsigned long shm_nattch;   //当前使用共享内存的进程数  
 time_t shm_atime;   //最后一次附加操作时间  
 time_t shm_dtime;   //最后一次分离操作时间  
 time_t shm_ctime;   //最后一次修改时间  

struct shmid_ds
{
struct ipc_perm shm_perm; //共享内存的ipc_perm结构
size_t shm_segsz; //共享内存区域大小,字节表示
pid_t shm_lpid; //最后一次调用shmop函数的进程ID
pid_t shm_cpid; //创建此共享内存的进程ID
unsigned short shm_lkcnt; //共享内存被锁定的时间数
unsigned long shm_nattch; //当前使用共享内存的进程数
time_t shm_atime; //最后一次附加操作时间
time_t shm_dtime; //最后一次分离操作时间
time_t shm_ctime; //最后一次修改时间
}共享内存基本操作

1,创建或打开一个共享内存(shmget)

C代码 
//create_shm.c  
#include<sys/types.h>  
#include<sys/ipc.h>  
#include<sys/shm.h>  
#include<stdio.h>  
 
#define BUFSZ 1024  
 
int main()  
{  
        int shm_id;     //共享内存ID  
        shm_id = shmget(IPC_PRIVATE,BUFSZ,0666);  
        if(shm_id < 0){  
                printf("shmget failed\n");  
                return -1;  
        }  
        printf("create shared memory succeed: %d\n",shm_id);  
        system("ipcs -m"); //查看共享内存ID  
        return 0;  

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

#define BUFSZ 1024

int main()
{
        int shm_id;     //共享内存ID
        shm_id = shmget(IPC_PRIVATE,BUFSZ,0666);
        if(shm_id < 0){
                printf("shmget failed\n");
                return -1;
        }
        printf("create shared memory succeed: %d\n",shm_id);
        system("ipcs -m"); //查看共享内存ID
        return 0;
}
2,附加共享内存到进程空间(shmat/shmdt)

C代码 
//attach_shm.c  
#include<sys/types.h>  
#include<sys/ipc.h>  
#include<sys/shm.h>  
#include<stdio.h>  
 
#define BUFSZ 1024  
 
int main()  
{  
        int *shm;  
        shm = shmat(104529925,NULL,0);  
        if(*shm == -1){  
                printf("shmat failed\n");  
                return -1;  
        }  
        printf("attach shared memory succeed: %d\n",*shm);  
        system("ipcs -m"); //查看共享内存调用状态   
        if(shmdt(shm) == -1){  
                printf("shmdt failed\n");  
                return -1;  
        }  
        system("ipcs -m"); //查看共享内存调用状态   
        return 0;  

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

#define BUFSZ 1024

int main()
{
        int *shm;
        shm = shmat(104529925,NULL,0);
        if(*shm == -1){
                printf("shmat failed\n");
                return -1;
        }
        printf("attach shared memory succeed: %d\n",*shm);
        system("ipcs -m"); //查看共享内存调用状态
        if(shmdt(shm) == -1){
                printf("shmdt failed\n");
                return -1;
        }
        system("ipcs -m"); //查看共享内存调用状态
        return 0;
}
3,共享内存控制函数(shmctl)

 

下面写个简单的例子

共享内存写端(write_shm.c)

C代码 
//write_shm.c  
#include<sys/types.h>  
#include<sys/ipc.h>  
#include<sys/shm.h>  
#include<stdio.h>  
 
typedef struct 
{  
        char name[4];  
        int age;  
}people;  
 
int main()  
{  
        int i;  
        char *t = 'a';  
        people *p_shm = NULL;  
        p_shm = shmat(104529925,NULL,0);  
        if(p_shm == NULL){  
                printf("shmat failed\n");  
                return -1;  
        }  
        for(i=0;i<5;i++) {  
                t += 1;  
                memcpy((*(p_shm+i)).name,&t,1);  
                (*(p_shm+i)).age = 20+i;  
        }  
        if(shmdt(p_shm) == -1){  
                printf("shmdt failed\n");  
                return -1;  
        }  
        return 0;  

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

typedef struct
{
        char name[4];
        int age;
}people;

int main()
{
        int i;
        char *t = 'a';
        people *p_shm = NULL;
        p_shm = shmat(104529925,NULL,0);
        if(p_shm == NULL){
                printf("shmat failed\n");
                return -1;
        }
        for(i=0;i<5;i++) {
                t += 1;
                memcpy((*(p_shm+i)).name,&t,1);
                (*(p_shm+i)).age = 20+i;
        }
        if(shmdt(p_shm) == -1){
                printf("shmdt failed\n");
                return -1;
        }
        return 0;
}
共享内存读端(read_shm.c)

C代码 
//read_shm.c  
#include<sys/types.h>  
#include<sys/ipc.h>  
#include<sys/shm.h>  
#include<stdio.h>  
 
typedef struct 
{  
        char name[4];  
        int age;  
}people;  
 
int main()  
{  
        int i;  
        char *t = 'a';  
        people *p_shm = NULL;  
        p_shm = shmat(104529925,NULL,0);  
        if(p_shm == NULL){  
                printf("shmat failed\n");  
                return -1;  
        }  
        for(i=0;i<5;i++) {  
                printf("name:%s age:%d\n",(*(p_shm+i)).name,(*(p_shm+i)).age);  
        }  
        if(shmdt(p_shm) == -1){  
                printf("shmdt failed\n");  
                return -1;  
        }  
        return 0;  

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

typedef struct
{
        char name[4];
        int age;
}people;

int main()
{
        int i;
        char *t = 'a';
        people *p_shm = NULL;
        p_shm = shmat(104529925,NULL,0);
        if(p_shm == NULL){
                printf("shmat failed\n");
                return -1;
        }
        for(i=0;i<5;i++) {
                printf("name:%s age:%d\n",(*(p_shm+i)).name,(*(p_shm+i)).age);
        }
        if(shmdt(p_shm) == -1){
                printf("shmdt failed\n");
                return -1;
        }
        return 0;
}先后编译执行"写代码"与"读代码",结果如下

Txt代码 
root$ ./write_shm.out   
root$ ./read_shm.out   
name:b age:20 
name:c age:21 
name:d age:22 
name:e age:23 
name:f age:24

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值