共享内存之System V共享内存区(笔记)

概述:

    System V共享区在概念上类似于POSIX共享内存区。代之以调用shm_open后调用mmap的是,先调用shmget,再调用shmat。

相关函数:

   shmdt函数:

 int shmget(key_t key, size_t size, int shmflg);  返回:若成功返回为共享内存区对象,若出错返回-1。

     key既可以是ftok的返回值,也可以是IPC_PRIVATE。

    size以字节为单位指定内存的区的大小。当实际操作为创建一个新的共享内存区时,必须指定一个不为0的size的值。如果实际操作为访问一个已经存在的共享内存区,那么size为0。

    oflag表示权限组合。

typedef struct stu
{
        char name[32];
        int age;
}STU;

int main(int argc,char *argv[])
{

        int shmid;
        shmid = shmget(1234,sizeof(STU),IPC_CREAT | 0666);
        if(shmid == -1)
                ERR_EXIT("shmget");

shmat函数:

  void *shmat(int shmid, const void *shmaddr, int shmflg);返回:若成功则为映射区的起始地址,若出错则返回-1.

    其中shmid是由shemget返回的标识符。shmat的返回值是所指定的共享内存区在调用进程内的起始地址。确定这个地址的规则如下:    

        如果shmaddr是一个空指针,那么系统替调用者选择地址。

        如果shmaddr是一个非空指针,那么返回地址取决于调用者是否给flag参数指定了SHM_RND。

            如果没有指定SHM_RND,那么相应的共享内存区附接到有shmaddr参数指定的地址;

            如果指定了SHM_RND,那么相应的共享内存区附接到有shmaddr参数指定的地址向下舍入SHMLBA常值。

       flag表示权限组合。

  STU *p;
        p = shmat(shmid,NULL,0);
        if(p == (void*)-1)
                ERR_EXIT("shmat");

shmdt函数:

      int shmdt(const void *shmaddr);返回:若成功返回0,若出错返回-1

当一个进程完成某个共享内存区的使用时,它可调用shmdt断接这个内存区。

  shmdt(p);

shmctl函数:

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

    shmctl提供了对一个内存区的多种操作。该函数提供了三个命令:

        IPC_RMID:从系统中删除由shmid标识的共享内存区并拆除它。

     IPC_SET: 给所指定的共享内存区设置其shmid_ds结构的以下三个成员:shm_perm.uid、shm_perm.gid和shm_perm.mode 。

        IPC_STAT:(通过buff参数)向调用者返回所指定共享内粗去当前的shmid_ds结构。

注:参考UNIX网络编程卷二:进程间同信

完整验证代码:

    读:

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

#include <sys/stat.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#define ERR_EXIT(m)				\
		do				\
		{				\
			perror(m);		\
			exit(EXIT_FAILURE);	\
		}while(0);			\

typedef struct stu
{
	char name[32];
	int age;
}STU;

int main(int argc,char *argv[])
{

	int shmid;
	shmid = shmget(1234, 0, 0);
	if(shmid == -1)
		ERR_EXIT("shmget");	
	STU *p;
	p = shmat(shmid,NULL,0);
	if(p == (void*)-1)
		ERR_EXIT("shmat");


	printf("name = %s\nage=%d\n",p->name,p->age);
	memcpy(p,"quit",4);
	shmdt(p);

	return 0;
}

    写:

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

#include <sys/stat.h>
#include <fcntl.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#define ERR_EXIT(m)				\
		do				\
		{				\
			perror(m);		\
			exit(EXIT_FAILURE);	\
		}while(0);			\

typedef struct stu
{
	char name[32];
	int age;
}STU;

int main(int argc,char *argv[])
{

	int shmid;
	shmid = shmget(1234,sizeof(STU),IPC_CREAT | 0666);
	if(shmid == -1)
		ERR_EXIT("shmget");	
	STU *p;
	p = shmat(shmid,NULL,0);
	if(p == (void*)-1)
		ERR_EXIT("shmat");

	strcpy(p->name,"lisi");
	p->age = 20;
	
	while(1)
	{
		if(memcmp(p,"quit",4) == 0)
			break;
	}
	shmdt(p);
	shmctl(shmid, IPC_RMID, NULL);

	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_34938530/article/details/80040433
今日推荐