代码之家  ›  专栏  ›  技术社区  ›  Ash

如何将结构存储和检索到C中的共享内存区域

  •  6
  • Ash  · 技术社区  · 14 年前

    对于uni分配,我需要创建一个最多包含10个文件名的循环列表,然后将这些文件名存储在共享内存区域中,以便2个子进程可以读/写该列表(使用信号量控制访问)。问题是,我完全是一个新手,我感到失落和绝望,因为它完全超出我的深度。我需要一些帮助来填补我知识的漏洞。

    现在,我只是一次只关注一个问题,而现在,我只想把循环列表放到共享内存区域。

    到目前为止我有:

    typedef struct FILE
    {
       struct FILE *f_link;  /* forward link for linked list */
       char name[255];       /* name of the file */
    
    } FILE_entry;
    

    作为我的结构,它将保存对下一个文件的引用(f_link)。这样,我就可以调用->f戋link来获取列表中的下一项,而第10个元素的f戋link将直接指向第1个元素。这样做的原因是,我可以不使用迭代器直接遍历列表(不必像使用数组那样检查列表的结尾)。

    我也知道我需要用 shmget 为了得到记忆区域,我明白了,我通过了 共享存储区 一个键,一个大小和一个标志(我没有得到),它返回一个int类型的标识符。

    所以我的问题是2倍。如何将链接列表存储到共享内存区域-如何从共享内存区域访问它?

    4 回复  |  直到 14 年前
        1
  •  9
  •   Fabian Giesen    14 年前

    shmget 只需保留一些共享内存,比如在磁盘上创建一个固定大小的文件。标志是一个权限掩码(如 mode 参数 open )在低9位加上一些额外的标志, IPC_CREAT IPC_EXCL ,对应于 O_CREAT O_EXCL 对于 打开 . 要实际访问该内存,需要将其映射到进程的地址空间(“附加”它-类似于 mmap 对于文件)。这是用 shmat (返回一个指针)。然后你需要分配你的 FILE 从指针构造。整个过程如下:

    int id;
    FILE_entry *entries;
    
    id = shmget(key, N * sizeof(FILE_entry), IPC_CREAT | 0644);
    entries = (FILE_entry *) shmat(id, NULL, 0);
    
    // you can now access entries as if it was a N-element array.
    // to turn it into a circular list, link the entries appropriately.
    

    映射之后,您可以像使用常规内存一样使用它,因为 有规律的记忆。这就是重点!

    编辑 :我忘了提一个重要的警告。将链表放入这样的共享内存段只有当所有相关进程将其映射到同一地址时才有效!所以你要么这样做(使用 连接共享内存 )或者从指针切换到相对于共享内存范围的基址的偏移量。那意味着把你的 next 从指针到 ptrdiff_t 并在加载时添加映射内存范围的基址(在存储时减去它)。

        2
  •  2
  •   Nicholas Knight    14 年前

    你打电话来 shmat(identifier, NULL, 0) ,返回指向进程中共享内存映射到的位置的指针。在该位置创建对象,或者 memcpy / memmove 他们去了那个地方。

    你可能会发现 Beej's Unix IPC guide 有用的是,它包含一个专门关于共享内存的部分。

        3
  •  2
  •   Carlos Melo    14 年前

    在你拿到钥匙之后 shmget ,您必须使用它通过 shmat . 以下是一些示例:

    int shmid;
    key_t key;
    FILE* shm;
    
    shmid = shmget(key, sizeof(FILE) * 10, IPC_CREAT | 0666);
    shm = shmat(shmid, NULL, 0);
    

    这样,您就可以使用 shm 指针。在这些链接中,您可以看到 共享存储区 连接共享内存 :

    http://linux.die.net/man/2/shmget

    http://linux.die.net/man/2/shmat

    然后看看 http://www.cplusplus.com 供参考。它还包含C引用。

    我不知道我是否足够清楚,所以,给我一些意见,如果有必要的话,我会给你一些启发。

    编辑:在这个网站上你可以找到一个非常简单的例子: http://simplestcodings.blogspot.com/2010/08/ipc-shared-memory-implementation-in-c.html

        4
  •  1
  •   James Anderson    14 年前

    对于标志,如果需要分配新的共享内存段,至少需要指定IPCXCREATE,否则,如果没有找到一个共享内存段,它将看起来是RAN现有的SeMeNT。

    其次,由于共享内存段是一个连续的内存块,因此您需要能够将所有10个文件条目结构存储在一起(或者分配10个共享内存段——糟糕!).

    因此,您确实需要为至少10个文件结构的数组设置足够的内存。

    最后一个文件和文件条目真的是坏名字!使用一些不太通用的东西,比如MY FILE REF和MyFileRefEntry。