PostgreSQL shm_toc 共享内存管理
1. shm_toc 描述
shm_toc 是共享内存段表内容管理(shared memory segment table of contents),通俗点说,就是对一块内存区域的管理,能够像表格一样,按照 key-value 的形式管理内存。
内存的开始位置,存放 shm_toc 结构体,用于管理这块内存的总大小、已经分配的大小、当前 key 的数量等元信息。shm_toc 管理的内存其存储的内容总是以 key-value 的形式存在,key 放到 toc_entry 中,toc_entry 是动态数组,从内存的开始位置向尾部增长,而 value 存储在内存的尾部,向头部增长。如下:
toc_entry[0] toc_entry[1] ... value[1] value[0]
当 toc_entry[n] 与 values[n] 重叠时,也就意味着这块内存没有足够的空间来存放这对 key-value 了。
2. shm_toc 数据结构
key 是一个 64 位整数,offset 是此 key 关联的内存地址到 shm_toc 起始位置的偏移。
源码位置:src/backend/storage/ipc/shm_toc.c
typedefstructshm_toc_entry { uint64 key; /* Arbitrary identifier */ Size offset; /* Offset, in bytes, from TOC start */ }shm_toc_entry; structshm_toc { uint64 toc_magic; /* Magic number identifying this TOC */ slock_t toc_mutex; /* Spinlock for mutual exclusion */ Size toc_total_bytes; /* Bytes managed by this TOC */ Size toc_allocated_bytes; /* Bytes allocated of those managed */ uint32 toc_nentry; /* Number of entries in TOC */ shm_toc_entry toc_entry[FLEXIBLE_ARRAY_MEMBER]; };
3. shm_toc 主要函数
shm_toc *
shm_toc_create(uint64 magic, void *address, Size nbytes)
创建一个 shm_toc,用来管理大小为 nbytes 的内存 address,返回的 shm_toc 实际上就是 address。
shm_toc *
shm_toc_attach(uint64 magic, void *address)
检查 address 所属的 shm_toc 的 magic 是否与给定的 magic 一致,如果不一致,返回 NULL,如果一致,返回该 shm_toc,也就是 address。
void *
shm_toc_allocate(shm_toc *toc, Size nbytes)
从 shm_toc 里面分配一个大小为 nbytes 的内存,返回该内存地址。这段内存被标记为已分配,但是未添加 key 与之关联。
Size
shm_toc_freespace(shm_toc *toc)
返回 shm_toc 里面的空闲空间大小。
void
shm_toc_insert(shm_toc *toc, uint64 key, void *address)
将 shm_toc 里面分配的内存与 key 进行关联。
void *
shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
返回 key 所对应的内存地址。
4. shm_toc 常用方法
shm_toc 常用于多进程共享内存的管理,多个进程使用共享内存进行通信。
(1)进程 A 调用 shm_toc_create 函数,创建一个 shm_toc 对象
(2)进程 A 调用 shm_toc_allocate 分配一块内存,调用 shm_toc_insert 与特定 key 关联
(3)进程 B 调用 shm_toc_lookup 获取某个 key 关联的内存
shm_toc 并不对所管理的内存进行释放,由调用者对这块内存做整体释放。
本文涉及的源码版本:pg11
文章评论