【问题标题】:Linux: Implementing linked list in shared memoryLinux:在共享内存中实现链表
【发布时间】:2013-01-29 21:09:50
【问题描述】:

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

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

对不起,糟糕的解释:/

【问题讨论】:

  • 你的结构没有“next”指针(或偏移量),所以你只是在创建一个数组,而不是一个链表。
  • 是的,它没有:) 假设我添加了“struct list_head list;”在结构中。

标签: c linux linked-list shared-memory


【解决方案1】:

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

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

【讨论】:

  • 是的,这就是为什么我想用“数组”来做(返回开头的偏移量)。 MAX 成员数是已知值,所以可能会更容易......
  • @Meh - 如果您的共享内存块在所有进程中的地址不同,您可以使用“从共享内存空间开始的偏移量”作为next“指针”你的链表。这样,“指针”在任何看到链表的进程中都是有意义的(尽管它需要通过指针算术访问它们,例如通过使用数组索引表示法)。
猜你喜欢
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 2014-02-14
  • 1970-01-01
相关资源
最近更新 更多