访问IPC_PRIVATE生成的key_t

Ant*_* O. 3 c ipc message-queue shared-memory

我正在尝试同步并使一些线程/进程为项目进行通信,并且理想情况下我希望访问它们之间的一些共享内存块,而不会让它们与其他进程/资源发生冲突。

我知道 IPC_PRIVATE 在调用shmget()创建它时会生成一个唯一的密钥,但是如果我随后需要该密钥在其他进程中的某个位置打开该区域,我如何访问该生成的key_t值以便将其发送到其他进程?

我目前正在通过 IPC 消息队列发送数据,因此我可以发送 shmid 值,但据我所知,这不起作用,因为 shmid 值对于每个进程都是唯一的。

我没有其他选择,只能尝试ftok()一些随机文件吗?我是否必须为我想要创建的不同共享内存的每个块选择不同的文件?

感谢您的时间。

Joh*_*ger 5

我知道 IPC_PRIVATE 在调用 shmget() 创建它时会生成一个唯一的密钥

不,你误会了。 IPC_PRIVATE生成a key_t,它a key_t。这种特殊情况key_t会引发特殊行为,shmget()即始终创建新段,忽略除模式位之外的所有标志位。

如果我需要该密钥在其他进程中的某个位置打开该区域,我如何访问生成的 key_t 值以便我可以将其发送到其他进程?

由于您总是使用 获得一个新段IPC_PRIVATE,因此您无法通过每个进程通过该键独立获取共享内存段来在进程之间共享内存。相反,对于通过这样的段进行通信的两个或多个进程(2021-12-19 插入),它们可以交换其中一个进程从中获取的 shmid shmget(),或者它们都必须从创建它的共同祖先进程继承它(或者创建它的进程)。彼此之间没有这种关系的进程不能使用密钥IPC_PRIVATE来访问同一段。

我没有其他选择,只能试试 ftok() 和一些随机文件吗?我是否必须为我想要创建的不同共享内存的每个块选择不同的文件?

由于您使用的是 System-V 共享内存,因此您可以选择ftok()根据现有路径生成密钥,但它不必是任意文件。您可以使用具有特定协作进程组特征的文件路径——输入文件、工作目录或类似文件。此外,ftok()还使用整数“项目 ID”,您可以使用它来区分不相关的运行,或用于不同目的或类似目的的多个不同键。如果你没有其他好的方法来区分,你可以在那里选择一些指定进程的进程ID。

顺便说一句,请注意,System-V IPC 接口非常笨重。它们确实有一些显着的特征,有时可能会使它们更受欢迎,但较新的 POSIX 接口(shm_open()等)通常是更好的选择。然而,POSIX 版本并没有为您所询问的问题提供特别更好的解决方案。