我想知道是否可以在共享内存(C、Linux)中创建链表。
假设我有一个创建共享内存并返回指向该内存的指针的库。示例:
// in lib header
typedef struct _SHM_STR_ {
int i;
char c;
} SHM_STR_t;
// in libomg.so
void lib_ret_shmem(SHM_STR_t** shm_pt)
{
int shm_fd;
SHM_STR_t *shm_map;
if ((shm_fd = shm_open(SHM_FILE, (O_CREAT | O_EXCL | O_RDWR), (S_IREAD | S_IWRITE))) > 0) {
//first time created; init
...
} else if ((shm_fd = shm_open(SHM_FILE, (O_CREAT | O_RDWR), (S_IREAD | S_IWRITE))) < 0) {
return 1;
}
ftruncate(shm_fd, 20*sizeof(SHM_STR_t));
shm_map = (SHM_STR_t *)mmap(0, 20*sizeof(SHM_STR_t), (PROT_READ | PROT_WRITE), MAP_SHARED, shm_fd, 0)
...
// add new member
// linked list or work with the offset in the shared mem?
// increment pointer with offset and return in:
*shm_pt = shm_map;
}
// in proc1.c something like this
int main(int argc, char *argv[])
{
SHM_STR_t *ppp = NULL;
lib_ret_shmem(&ppp);
printf("%d %c\n", ppp->a, ppp->b);
return 0;
}
所以在库中我已经为 20 个结构 SHM_STR_t 分配了足够的共享内存。
每次调用 lib_ret_shmem() 时添加新成员的最佳方法是什么?
我应该使用内存基地址的偏移量(或数组)吗?喜欢成员 [3] 我会返回类似的东西
*shm_pt = shm_map + 3;
或者可以在此内存中创建链表?我感觉 *next 不会指向正确的内存。
对于糟糕的解释感到抱歉:/
最佳答案
如果您打算跨进程共享链表,那么您永远不能使用 malloc() 在链表中创建新节点;你需要一些其他的分配机制。如果所有分配的大小都相同,您可以轻松地创建一个特殊的 shared_malloc() 函数,该函数将下一个分配从空闲节点列表中拉出,以及一个 shared_free() 函数,该函数将一个节点返回给空闲节点列表。这并不难。当您创建共享内存池时,只需将大的 mmap 分配分成您需要大小的单独内存块(或者如果您需要多个大小,则将它们全部设为最大大小),然后将它们全部初始化使用指向内存范围中下一个人的“下一个”指针,并将“空闲列表”头指针分配给列表中的第一个。任何时候你需要另一个分配,捕获空闲列表头部的那个,并将空闲列表头指针重新分配给列表中的下一个。
如果您在多线程/多进程环境中执行此操作(事实上,如果不是,您为什么要关心共享内存?),那么您需要在 shared_malloc() 和 shared_free() 中考虑并发性功能...也许使用信号量或互斥量。 (考虑如果进程 A 刚刚获取下一个空闲节点,但还没有调整头指针,并且进程 B 中断并获取空闲列表的顶部会发生什么......现在两个进程都具有相同的节点。 ...)
关于c - Linux:在共享内存中实现链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14592341/