前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux共享内存与子进程继承

Linux共享内存与子进程继承

作者头像
mingjie
发布2022-11-30 16:11:06
4K0
发布2022-11-30 16:11:06
举报
文章被收录于专栏:Postgresql源码分析

总结

  • Postgresql使用mmap创建匿名内存块作为共享内存使用。
  • Postgresql也会使用system v的接口申请ipc共享内存(本篇)。

目前PG15中只有这一个变量会放在ipc的共享内存中了,其他都在mmap申请的匿名块中。

代码语言:javascript
复制
typedef struct PGShmemHeader	/* standard header for all Postgres shmem */
{
	int32		magic;			/* magic # to identify Postgres segments */
#define PGShmemMagic  679834894
	pid_t		creatorPID;		/* PID of creating process (set but unread) */
	Size		totalsize;		/* total size of segment */
	Size		freeoffset;		/* offset to first free space */
	dsm_handle	dsm_control;	/* ID of dynamic shared memory control seg */
	void	   *index;			/* pointer to ShmemIndex table */
#ifndef WIN32					/* Windows doesn't have useful inode#s */
	dev_t		device;			/* device data directory is on */
	ino_t		inode;			/* inode number of data directory */
#endif
} PGShmemHeader;
  • IPC的共享内存使用分为三步:
    • 申请:shm_id申请共享内存段,申请后可以使用ipcs -m查询
    • 关联:shmat将共享内存映射到自己的内存空间中
    • 解除关联:shmdt将共享内存映射删除
    • 释放:shmctl IPC_RMID删除共享内存段
  • IPC申请的共享内存关联后可以拿到映射地址,映射地址子进程可以直接使用。

IPC的共享内存实例1

代码语言:javascript
复制
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h>

#define IPCProtection (0600) /* access/modify by user only */

int main(void)
{
	int shm_id;
	char *memAddress;
	struct shmid_ds shmbuffer;
	/* $PGDATA */
	char *DataDir = "/tmp/s1";
	struct stat statbuf;

	stat(DataDir, &statbuf);
	shm_id = shmget(statbuf.st_ino, 1073741824, IPC_CREAT | IPC_EXCL | IPCProtection);

	printf("shared memory key: %ld\n", statbuf.st_ino);

	/* attaches System V shared memory segment */
	memAddress = (char *)shmat(shm_id, 0, 0);
	printf("shared memory attached at address %p\n", memAddress);

	shmctl(shm_id, IPC_STAT, &shmbuffer);
	printf("segment size:%ld\n", shmbuffer.shm_segsz);

	sprintf(memAddress, "Hello,world.");
	/* detaches */
	shmdt(memAddress);

	/* attaches System V shared memory segment */
	memAddress = (char *)shmat(shm_id, (void *)0x500000, 0);

	printf("shared memory reattched at address %p\n", memAddress);
	printf("%s\n", memAddress);
	shmdt(memAddress);

	/* release shared memory segment */
	shmctl(shm_id, IPC_RMID, 0);

	return 0;
}

// gcc -o main1 -Wall -g -ggdb -O0 -g3 -gdwarf-2 main1.c

执行结果:

代码语言:javascript
复制
shared memory key: 527687
shared memory attached at address 0x7fb7253e1000
segment size:1073741824
shared memory reattched at address 0x500000
Hello,world.

IPC的共享内存实例2:子进程

代码语言:javascript
复制
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#define IPCProtection (0600) /* access/modify by user only */

int main(void)
{
	int shm_id;
	char *memAddress;
	struct shmid_ds shmbuffer;
	/* $PGDATA */
	char *DataDir = "/tmp/s1";
	struct stat statbuf;

	stat(DataDir, &statbuf);
	shm_id = shmget(statbuf.st_ino, 1073741824, IPC_CREAT | IPC_EXCL | IPCProtection);

	printf("shared memory key: %ld\n", statbuf.st_ino);

	/* attaches System V shared memory segment */
	memAddress = (char *)shmat(shm_id, 0, 0);
	printf("shared memory attached address %p\n", memAddress);

	shmctl(shm_id, IPC_STAT, &shmbuffer);
	printf("segment size:%ld\n", shmbuffer.shm_segsz);

	

	/* fork */
	pid_t pid = fork();
	if (pid > 0)
	{
		sprintf(memAddress, "Hello child.");
		wait(NULL);
		printf("%s\n", (char *)memAddress);
	}
	else if (pid == 0)
	{
		printf("%s\n", (char *)memAddress);
		sprintf(memAddress, "Hello parent.");
	}

	/* release shared memory segment */
	shmctl(shm_id, IPC_RMID, 0);
	return 0;
}

// gcc -o main2 -Wall -g -ggdb -O0 -g3 -gdwarf-2 main2.c

执行结果

代码语言:javascript
复制
shared memory key: 527687
shared memory attached address 0x7f79de044000
segment size:1073741824
Hello child.
Hello parent.
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
  • IPC的共享内存实例1
  • IPC的共享内存实例2:子进程
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档