Linux系统编程66 进程,线程间通信4 - 共享内存

本文学习自 李慧琴老师 的Linux系统编程


shmget() 分配一个System V共享内存段

NAME
分配一个System V共享内存段
       shmget - allocates a System V shared memory segment

SYNOPSIS
       #include <sys/ipc.h>
       #include <sys/shm.h>

/*
key:
如果没有亲缘关系的进程中 创建和获取 和之前 消息队列是一样的
如果在有亲缘关系的进程中,fork()之后,每一个子进程都可以拿到父进程创建的 key值,此时不再关心key值,此时可以设置为 IPC_PRIVATE,表示该IPC 为 匿名IPC 不需要ftok

size:要设置的共享内存的大小
shmflg : 当前共享内存创建的特殊要求,当key 为IPC_PRIVATE时, -semflg设置为IPC_CREAT
shmid = shmget(IPC_PRIVATE,MEMSIZE,IPC_CREAT|0600);
*/

   int shmget(key_t key, size_t size, int shmflg);

RETURN VALUE
       On success, a valid shared memory identifier is returned.  On error, -1 is returned, and errno is set to indicate the error.

shmat()把共享内存映射过来
shmdt() 把共享内存进行解除映射

NAME
       shmat, shmdt - System V shared memory operations

SYNOPSIS
       #include <sys/types.h>
       #include <sys/shm.h>

/* 把共享内存映射过来
shmid:共享内存ID
shmaddr :需要映射到我当前空间的具体位置,写空 表示函数帮忙在当前进程空间中寻找一块可用的内存地址。
shmflg : 特殊要求,0为没有特殊要求
*/

   void *shmat(int shmid, const void *shmaddr, int shmflg);

//把共享内存进行解除映射
   int shmdt(const void *shmaddr);

RETURN VALUE
       On success, shmat() returns the address of the attached shared memory segment; on error, (void *) -1 is returned, and errno is set to indicate the cause  of  the
       error.

   On success, shmdt() returns 0; on error -1 is returned, and errno is set to indicate the cause of the error.

shmctl() System V共享内存控制 如销毁

NAME
System V共享内存控制  如销毁
       shmctl - System V shared memory control

SYNOPSIS
       #include <sys/ipc.h>
       #include <sys/shm.h>

/*
shmid,共享内存ID
cmd : 命令动作
如:IPC_RMID 销毁
buf,是否需要传参,需要传递的参数
*/
       int shmctl(int shmid, int cmd, struct shmid_ds *buf);

实验:父子进程进 使用 共享内存 进行通信,对比之前使用内存映射mmap(),还是mmap()使用更简单一点。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <string.h>
#include <wait.h>
#define MEMSIZE 1024

int main()
{
	int shmid;
	pid_t pid;
	char *ptr;

	shmid = shmget(IPC_PRIVATE,MEMSIZE,IPC_CREAT|0600);
	if(shmid < 0)
	{
		perror("msgget");
		exit(1);
	}

	pid = fork();
	if(pid < 0)
	{
		perror("fork() failed");
		exit(1);
	}

	if(pid == 0)
	{
		ptr = shmat(shmid,NULL,0);
		if(ptr == (void *)-1)
		{
			perror("shmat");
			exit(1);
		}	
		
		strcpy(ptr,"Hello!");
		shmdt(ptr);
		exit(0);
	}
	else
	{
		wait(NULL);
		ptr = shmat(shmid,NULL,0);
		if(ptr == (void *)-1)
		{
			perror("shmat");
			exit(1);
		}
		puts(ptr);
		shmdt(ptr);
		shmctl(shmid,IPC_RMID,NULL);
		exit(0);
		
	}	

	exit(0);
	

}

猜你喜欢

转载自blog.csdn.net/LinuxArmbiggod/article/details/114919517
今日推荐