对于 uni 分配,我需要创建一个最多包含 10 个文件名的循环列表,然后将它们存储在共享内存区域中,以便 2 个子进程可以读/写列表(使用信号量来控制访问).麻烦的是,我是一个完全的 C 新手,我感到失落和绝望,因为它完全超出了我的理解范围。我需要一些帮助来“填补我的知识漏洞”。
现在,我只是一次专注于它一个问题,目前,我只是试图将我的循环列表放入共享内存区域。
到目前为止我有:
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 定向回第一个。我这样做的原因是我可以在没有迭代器的情况下简单地遍历列表(并且永远不必像使用数组那样检查列表的末尾)。
我也知道我需要使用shmget
来获取内存区域,我明白了,我通过shmget
一个键,一个大小和一个标志(哪个我不明白),它返回一个 int 类型的标识符。
所以我的问题是 2 倍。如何将我的链表存储到共享内存区域 - 我如何从共享内存区域访问它?
最佳答案
shmget
只是保留一些共享内存——就像在磁盘上创建一个固定大小的文件一样。标志是低 9 位中的权限掩码(如 open
的 mode
参数)加上一些额外的标志,IPC_CREAT
和 IPC_EXCL
,对应O_CREAT
和O_EXCL
,用于open
。要实际访问该内存,您需要将其映射到进程的地址空间(“附加”它 - 类似于文件的 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.
映射后,您可以像使用常规内存一样使用它 - 因为它 是常规内存。这就是重点!
编辑:我忘记提及的一个重要警告。像这样将链表放入共享内存段只有在所有相关进程都将其映射到同一地址时才有效!因此,您要么需要这样做(使用 shmat
的第二个参数),要么从指针切换到相对于共享内存范围基地址的偏移量。这意味着将您的 next
字段从指向 ptrdiff_t
的指针转换,并在您加载它时添加映射内存范围的基地址(并在您存储它时减去它)。
关于c - 我如何在 C 中将结构存储和检索到共享内存区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4263444/