如果访问共享内存的键是 shmget() 的返回值,那么拥有 key_t 有什么意义呢?

发布于 2024-10-01 19:22:31 字数 792 浏览 1 评论 0原文

当使用共享内存时,我们为什么要关心

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 type
key_t is actually just a long, 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 the ftok()
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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦行七里 2024-10-08 19:22:31

整个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 with rand as long as you have a way of passing the result to other processes that need to attach the shared memory.

行至春深 2024-10-08 19:22:31

是的,在使用 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 using shmget(). 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 :)

等你爱我 2024-10-08 19:22:31

shmid 值仅在单个进程的上下文中有效,而不同进程中的相同 key_t 值将允许它们打开相同的共享内存段。

这就是为什么您需要一个 key_t - 作为命名共享内存段的跨进程方式。至于 ftok(),正如其他答案所指出的,它用于减少两个不相关的进程组使用相同的 key_t 的概率价值。

shmid values are only valid in the context of a single process, whereas the same key_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 for ftok(), as the other answers have noted, that's used to reduce the probability of two unrelated groups of processes using the same key_t value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文