如果访问共享内存的键是 shmget() 的返回值,那么拥有 key_t 有什么意义呢?
当使用共享内存时,我们为什么要关心
key_t ftok(const char *path, int id);
在下面的代码中创建密钥?
key_t key;
int shmid;
key = ftok("/home/beej/somefile3", 'R');
shmid = shmget(key, 1024, 0644 | IPC_CREAT);
据我了解,访问给定共享内存需要的是 shmid
,而不是密钥。还是我错了?如果我们需要的是 shmid
,那么每次不只是创建一个随机密钥还有什么意义呢?
编辑
@Beej's Guide to Unix IPC可以阅读:
这个
key
废话怎么样?怎么办 我们创造一个?好吧,既然类型key_t
实际上只是一个long
,你可以 使用任何你想要的数字。但如果 你对数字和一些进行硬编码 其他不相关的程序硬编码 相同的号码但想要另一个队列? 解决方案是使用ftok()
生成密钥的函数 两个参数。
读到这里,它给我的印象是,需要附加到共享内存块的内容是关键。但这不是真的,不是吗?
When using shared memory, why should we care about creating a key
key_t ftok(const char *path, int id);
in the following bit of code?
key_t key;
int shmid;
key = ftok("/home/beej/somefile3", 'R');
shmid = shmget(key, 1024, 0644 | IPC_CREAT);
From what I've come to understand, what is needed to access a given shared memory is the shmid
, not the key. Or am I wrong? If what we need is the shmid
, what is the point in not just creating a random key every time?
Edit
@Beej's Guide to Unix IPC one can read:
What about this
key
nonsense? How do
we create one? Well, since the typekey_t
is actually just along
, you can
use any number you want. But what if
you hard-code the number and some
other unrelated program hardcodes the
same number but wants another queue?
The solution is to use theftok()
function which generates a key from
two arguments.
Reading this, it gives me the impression that what one needs to attach to a shared-memory block is the key. But this isn't true, is it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
整个System V IPC系统充满了这样的糟糕设计。 (糟糕的设计,我的意思是共享资源的一个很小的命名空间,你必须依靠像 ftok 这样的愚蠢技巧来获取密钥,并祈祷它不会与使用中的任何其他密钥发生冲突。 )
如果可能的话,我会假装它不存在,并尽可能使用 POSIX 共享内存(同样使用 POSIX 线程同步原语代替 System V 信号量)。我能想到的唯一需要 System V 共享内存的实例是 X 共享内存映像扩展以及其他 X 扩展。
编辑:为了更好地回答OP关于
ftok
用途的问题:key_t
通常是32位,是的,你可以选择32位你自己给自己编号,但问题是人类选择所有数字的可能性并不相同,而且碰撞的可能性太高了。ftok
允许您选择一个文件(对于您的应用程序来说是唯一的)和一个整数,并使用您选择的整数对文件的 inode 编号进行哈希处理,这应该会导致关键选项在整个应用程序中的分布更加均匀。键空间。当然,您也可以只使用rand
选择一个键,只要您有办法将结果传递给需要附加共享内存的其他进程即可。The whole System V IPC system is full of bad designs like this. (By bad designs, I mean a tiny namespace for shared resources where you have to rely on stupid tricks like
ftok
to get a key and pray it doesn't happen to conflict with any other keys in use.)If possible, I would pretend it doesn't exist and use POSIX shared memory instead whenever possible (and likewise POSIX thread synchronization primitives in place of System V semaphores). The only instance I can think of where you need System V shared memory is for the X shared-memory image extension and perhaps other X extensions.
Edit: To better answer OP's question about the purpose of
ftok
:key_t
is usually 32-bit and yes you could just pick a 32-bit number yourself, but the problem is that humans are not equally likely to pick all numbers, and the chance of collision is way too high.ftok
lets you choose a file (intended to be one unique to your application) and an integer and hash the file's inode number with your chosen integer, which should result in much more even distribution of key choices across the key space. Of course you could also just choose a key withrand
as long as you have a way of passing the result to other processes that need to attach the shared memory.是的,在使用
shmget()
打开共享内存后,您需要使用 shmid 来访问共享内存(使用shmat()
)。但是您将访问的特定共享内存块基于您正在使用的密钥,即希望通过 shm 进行通信的不同进程将需要使用相同的密钥。如果您只是使用随机数作为密钥,则可能会与其他一些不相关的程序发生冲突。我本来建议看一下 Beej 的 IPC 指南,但是我发现你已经找到了:)
Yes, you need to use the shmid to access the shared memory (using
shmat()
) after you've opened it usingshmget()
. But the specific block of shared memory that you'll be accessing is based on the key that you are using i.e. different process wishing to communicate via the shm will need to use the same key. If you just used a random number as a key, you might get a clash with some other unrelated program.I was going to suggest taking a look at Beej's Guide to IPC but I see you've already found it :)
shmid
值仅在单个进程的上下文中有效,而不同进程中的相同key_t
值将允许它们打开相同的共享内存段。这就是为什么您需要一个 key_t - 作为命名共享内存段的跨进程方式。至于 ftok(),正如其他答案所指出的,它用于减少两个不相关的进程组使用相同的 key_t 的概率价值。
shmid
values are only valid in the context of a single process, whereas the samekey_t
value in different processes will allow them to open the same shared memory segment.That's essentially why you need a
key_t
- as a cross-process way of naming a shared memory segment. As forftok()
, as the other answers have noted, that's used to reduce the probability of two unrelated groups of processes using the samekey_t
value.