Linux:在共享内存中实现链表

时间:2013-01-29 21:09:51

标签: c linux linked-list shared-memory

我想知道是否可以在共享内存(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;
}

所以在lib中我已经为20个结构SHM_STR_t分配了足够的共享内存。

每次调用lib_ret_shmem()时添加新成员的最佳方法是什么?

我应该使用内存(或数组)的基址的偏移吗?对于成员[3],我会返回类似

的内容
*shm_pt = shm_map + 3;

或者可以在这个内存中创建链表吗?我觉得*接下来不会指向正确的记忆。

抱歉可怕的解释:/

1 个答案:

答案 0 :(得分:1)

如果您打算跨进程共享链表,那么您永远不能使用malloc()在列表中创建新节点;你需要一些其他的分配机制。如果所有分配的大小都相同,那么您可以轻松地创建一个特殊的shared_malloc()函数,该函数从空闲节点列表中提取下一个分配,以及一个将节点返回给该节点的shared_free()函数。免费节点列表。这不是非常困难。当您创建共享内存池时,只需将大mmap的分配划分为您需要的单个内存块(或者如果您需要多个大小,然后将它们设置为最大的大小),并将它们全部初始化使用指向内存范围中下一个人的“下一个”指针,并将“空闲列表”头指针指定给列表中的第一个指针。任何时候你需要另一个分配,抓住空闲列表头部的那个,并将空闲列表头指针重新分配给列表中的下一个。

如果您在多线程/多进程环境中执行此操作(实际上,如果不是共享内存,为什么还要关注共享内存?),那么您需要考虑shared_malloc()&amp;中的并发性。 shared_free()函数...也许使用信号量或互斥量。 (考虑如果进程A刚刚抓住下一个空闲节点会发生什么,但是还没有调整头指针,进程B中断并且抓住空闲列表的顶部......现在两个进程都有相同的节点....)