目前PG15中只有这一个变量会放在ipc的共享内存中了,其他都在mmap申请的匿名块中。
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的共享内存使用分为三步:
IPC申请的共享内存关联后可以拿到映射地址,映射地址子进程可以直接使用。
#include
#include
#include
#include
#include
#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
执行结果:
shared memory key: 527687
shared memory attached at address 0x7fb7253e1000
segment size:1073741824
shared memory reattched at address 0x500000
Hello,world.
#include
#include
#include
#include
#include
#include
#include
#include
#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
执行结果
shared memory key: 527687
shared memory attached address 0x7f79de044000
segment size:1073741824
Hello child.
Hello parent.