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

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

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

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)

//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)

//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)

//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)

//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;
}

先后编译执行"写代码"与"读代码",结果如下

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

猜你喜欢

转载自ciaos.iteye.com/blog/1860119
今日推荐