Ash*_*Ash 6 c unix shared-memory
对于单一赋值,我需要创建一个最多10个文件名的循环列表,然后将它们存储在共享内存区域中,这样2个子进程就可以读/写列表(使用信号量来控制访问).麻烦的是,我是一个全新的C新手,我感到失落和绝望,因为它完全超出了我的深度.我需要一些帮助来填补我的知识.
现在,我只是一次只关注它一个问题,而目前,我只是试图将我的循环列表放入共享内存区域.
到目前为止,我有:
typedef struct FILE
{
struct FILE *f_link; /* forward link for linked list */
char name[255]; /* name of the file */
} FILE_entry;
Run Code Online (Sandbox Code Playgroud)
作为我的结构,它将保存对下一个文件的引用(f_link).这样我就可以调用 - > f_link来获取列表中的下一个项目,并且第10个元素的f_link将直接返回到第1个.我这样做的原因是我可以在没有迭代器的情况下简单地遍历列表(并且不必像使用数组那样检查列表的结尾).
我也知道我需要用来shmget
获取内存区域,我理解它,我传递shmget
一个键,一个大小和一个标志(我没有得到),它返回一个int类型的标识符.
所以我的问题是2折.如何将链接列表存储到共享内存区域 - 如何从共享内存区域访问它?
shmget
只保留一定数量的共享内存 - 比如在磁盘上创建固定大小的文件.标志是低9位的权限掩码(如mode
参数open
)加上一些额外的标志,IPC_CREAT
并且IPC_EXCL
对应于O_CREAT
和O_EXCL
for 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.
Run Code Online (Sandbox Code Playgroud)
映射后,您可以像常规内存一样使用它 - 因为它是常规内存.这就是重点!
编辑:我忘了提一个重要的警告.将链接列表放入这样的共享内存段只有在所有相关进程将其映射到同一地址时才有效!因此,您需要执行此操作(使用第二个参数shmat
)或从指针切换到相对于共享内存范围的基址的偏移量.这意味着将next
字段从指针转换为a ptrdiff_t
并在加载时添加映射内存范围的基址(并在存储时减去它).