访问由 IPC_PRIVATE 生成的 key_t
Accessing key_t generated by IPC_PRIVATE
我正在尝试同步并使一些 threads/processes 为项目进行通信,理想情况下我希望访问它们之间的一些共享内存块,而不会让它们与其他 processes/resources 发生冲突.
我知道 IPC_PRIVATE 会在调用 shmget()
创建它时生成一个唯一的密钥,但是如果我随后需要该密钥在其他进程中的某处打开该区域,我该如何访问生成的那个key_t
值以便我可以将它发送到其他进程?
我目前正在通过 IPC 消息队列发送数据,因此我可以发送 shmid 值,但据我所知这是行不通的,因为 shmid 值对于每个进程都是唯一的。
除了 ftok()
和一些随机文件,我别无选择吗?我是否必须为每个要创建的不同共享内存块选择不同的文件?
感谢您的宝贵时间。
I know IPC_PRIVATE will generate a unique key when calling shmget() to create it
不对,你误会了。 IPC_PRIVATE
不会 生成 一个 key_t
,它 是 一个 key_t
。这个特殊的 key_t
引出了 shmget()
的特殊行为,即始终创建一个新段,忽略除模式位之外的所有标志位。
if I then need that key to open that region somewhere in other processes, how can I access that generated key_t value so that I can send it to the other process?
由于您总是通过 IPC_PRIVATE
获得一个新段,因此您无法在进程之间共享内存,每个进程都通过该键独立获取共享内存段。相反,对于通过这样的段进行通信的两个或多个进程,(插入 2021-12-19)它们可能会交换其中一个从 shmget()
或 获得的 shmid他们必须可能都从创建它的共同祖先进程(或是创建它的进程)继承了它。相互之间没有这种关系的进程不能使用IPC_PRIVATE
键访问同一个段。
Do I have no other options but try luck with ftok() and some random files? Do I have to choose a different file for each block of different shared memory I wish to create?
由于您使用的是 System-V 共享内存,因此您可以选择使用 ftok()
根据现有路径生成密钥,但不必是 任意文件。您可以使用具有特定协作进程组特征的文件的路径——输入文件、工作目录或类似文件。此外,ftok()
还使用一个整数“项目 ID”,您可以使用它来区分不相关的运行,或用于不同目的或类似用途的多个不同键。如果你没有其他好的区分方法,你可以在那里选择一些指定进程的进程号。
请注意,顺便说一下,System-V IPC 接口非常笨重。它们确实有一些与众不同的特性,有时可能会使它们更受欢迎,但较新的 POSIX 接口(shm_open()
等)通常是更好的选择。但是,POSIX 版本并未针对您提出的问题提供特别好的解决方案。
我认为上面的答案不正确。
首先,ipcrm
程序可以选择通过 id 而不是按键删除共享对象:
-m, --shmem-id shmid
Remove the shared memory segment identified by shmid after
the last detach is performed. in case of shared memory.
这个事实告诉我们 id 是全局的。
其次,我刚刚编写了一个创建消息队列的程序
IPC_PRIVATE
并且服务器进程(与客户端无关)能够响应
合并到传入消息中的消息 ID。
我记得大约 20 年前对共享内存做过同样的事情。
我正在尝试同步并使一些 threads/processes 为项目进行通信,理想情况下我希望访问它们之间的一些共享内存块,而不会让它们与其他 processes/resources 发生冲突.
我知道 IPC_PRIVATE 会在调用 shmget()
创建它时生成一个唯一的密钥,但是如果我随后需要该密钥在其他进程中的某处打开该区域,我该如何访问生成的那个key_t
值以便我可以将它发送到其他进程?
我目前正在通过 IPC 消息队列发送数据,因此我可以发送 shmid 值,但据我所知这是行不通的,因为 shmid 值对于每个进程都是唯一的。
除了 ftok()
和一些随机文件,我别无选择吗?我是否必须为每个要创建的不同共享内存块选择不同的文件?
感谢您的宝贵时间。
I know IPC_PRIVATE will generate a unique key when calling shmget() to create it
不对,你误会了。 IPC_PRIVATE
不会 生成 一个 key_t
,它 是 一个 key_t
。这个特殊的 key_t
引出了 shmget()
的特殊行为,即始终创建一个新段,忽略除模式位之外的所有标志位。
if I then need that key to open that region somewhere in other processes, how can I access that generated key_t value so that I can send it to the other process?
由于您总是通过 IPC_PRIVATE
获得一个新段,因此您无法在进程之间共享内存,每个进程都通过该键独立获取共享内存段。相反,对于通过这样的段进行通信的两个或多个进程,(插入 2021-12-19)它们可能会交换其中一个从 shmget()
或 获得的 shmid他们必须可能都从创建它的共同祖先进程(或是创建它的进程)继承了它。相互之间没有这种关系的进程不能使用IPC_PRIVATE
键访问同一个段。
Do I have no other options but try luck with ftok() and some random files? Do I have to choose a different file for each block of different shared memory I wish to create?
由于您使用的是 System-V 共享内存,因此您可以选择使用 ftok()
根据现有路径生成密钥,但不必是 任意文件。您可以使用具有特定协作进程组特征的文件的路径——输入文件、工作目录或类似文件。此外,ftok()
还使用一个整数“项目 ID”,您可以使用它来区分不相关的运行,或用于不同目的或类似用途的多个不同键。如果你没有其他好的区分方法,你可以在那里选择一些指定进程的进程号。
请注意,顺便说一下,System-V IPC 接口非常笨重。它们确实有一些与众不同的特性,有时可能会使它们更受欢迎,但较新的 POSIX 接口(shm_open()
等)通常是更好的选择。但是,POSIX 版本并未针对您提出的问题提供特别好的解决方案。
我认为上面的答案不正确。
首先,ipcrm
程序可以选择通过 id 而不是按键删除共享对象:
-m, --shmem-id shmid
Remove the shared memory segment identified by shmid after
the last detach is performed. in case of shared memory.
这个事实告诉我们 id 是全局的。
其次,我刚刚编写了一个创建消息队列的程序
IPC_PRIVATE
并且服务器进程(与客户端无关)能够响应
合并到传入消息中的消息 ID。
我记得大约 20 年前对共享内存做过同样的事情。