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

标签 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;
}

所以在库中我已经为 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/

相关文章:

c - 如何通过串行连接(蓝牙)获取 TCP/IP 数据包

c - 利用缓冲区溢出

pointers - 从非指针结构元素转到链表指针赋值

java - 这些 LinkedList 节点是否有资格进行垃圾回收?

c++ - 旧代码中的神秘行 "??!??!"

c++ - 我的应用程序在 KNearest::find_nearest 处崩溃

linux - 断开连接后保持 SSH session 运行

linux - 无法从 bash 脚本中获取带有空格的路径?

在 std::list 上使用删除时的 C++ 分段

c - pthread_create创建的线程是否与内核线程相同?