16

I have started reading message queues one of the IPC mechanism on Linux .But at very first step I have some very basic questions.

  1. Use of ftok() to generate unique ID (key) and what is unique ID which is to be generated.

  2. Can't we use simple a number to get our keys rather than using ftok()?

  3. What is the purpose of the argument key in the msget function?

    #include "sys/msg.h"
    key = ftok("/home/beej/somefile", 'b');
    msqid = msgget(key, 0666 | IPC_CREAT);
    
  4. What is the difference between msqid and key?

alk
  • 69,737
  • 10
  • 105
  • 255
Amit Singh Tomar
  • 8,380
  • 27
  • 120
  • 199

3 Answers3

36

The ftok function creates a sort of identifier to be used with the System V IPC functions (semget, shmget, msgget). Think of it like a filedescriptor: when you open a file, you pass a path to open and get a number in return that is then used for read and write to identify the file. The ftok function serves a similar purpose, but while the filedescriptor's scope is limited to just the process that called open (and its children), the ftok token is valid across the system.

The reason for the system scope is that you want two or more independent processes to have access to the same IPC resources. So if you have two programs, both of which execute key = ftok("/home/beej/somefile", 'b');, both will get the same token and can therefor access the same resources (semaphores, shared memory, message queues). That's the whole point of Inter Process Communication.

You cannot just use a "simple number" as you don't know whether the token might be for example an index to an system-internal table or something. In other words, you don't know how that token is used internally so you do need to use ftok.

The man page says: "The specified path must specify an existing file that is accessible to the calling process or the call will fail. Also, note that links to files will return the same key, given the same id." From this I assume that at least some ftok implementations create the token by looking up the inode number of the file specified by path and combine it with the second argument to create the token. The second argument exists simply so you can create a bunch of IPC resources (like several semaphores to protect different resources).

As for the difference of key_t (the value returned by ftok) and the value retured by msgget: the former gives you access to a bunch of IPC resources (semaphore, shared memory and message queue), while the later identifies a specific message queue.

DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • Thanks @Drak for your explanation,it is very helpful ,So can i think key as a name of message queues?? – Amit Singh Tomar Sep 09 '11 at 07:53
  • 4
    I'll try it in a more abstract way, maybe this helps: Imagine there are several rooms. In each room there is one box that can be filled with semaphores, one chalkboard (shared memory) and one box that can be filled with papers (messages). Now, `key` is the telling you which room to go to. Then with `msgget` you can get the box with papers (message queue) in that room. The `msgid` is then pointing to just that box without the need for the key again. – DarkDust Sep 09 '11 at 08:14
  • *you don't know how that token is used internally so you do need to use `ftok`.* `ftok()` provides absolutely zero guarantees that the returned `key_t` is unique. If the number of possible files in a file system and the 8 bits used from `id` is larger than the range of `key_t`, the result can not be unique even for different files in the same file system. And systems quite often have multiple file systems mounted so the opportunity for `key_t` collision is even greater. Linux uses a 32-bit `key_t`, which means once there are more than 16 million files, `key_t` values must be duplicated. – Andrew Henle Mar 23 '20 at 15:20
1
  1. I don't fully understand your question, but it generates a unique identifier to the system (not process) based on the file path given. This unique identifier (tied to path) allows different processes to bind to the same message queue.

  2. Yes, you could, if they designed it that way. But a file path is a more universal way of arriving at a common deterministic key generation mechanism that multiple processes can easily access.

  3. See 1 & 2

  4. msqid is analogous to a file handle, that you can send and receive messages to that handle. The key is what allows you to associate your hook into the message queue your interested in. As an analogy, if the key is to a file path in the global file system, then the msqid would be your process's handle to read/write to it.

Missaka Wijekoon
  • 883
  • 7
  • 10
-1
  1. What?

  2. That could work, but which one would you choose and who guarantees that other programs (or the system itself) won't use the same numbers? That would lead to confusion.

  3. The purpose is to provide a system-wide unique value in order to identify a message queue. As the manpage states,

    Typically, a best effort attempt combines the given proj_id byte, the lower 16 bits of the inode number, and the lower 8 bits of the device number into a 32-bit result. Collisions may easily happen, for example between files on /dev/hda1 and files on /dev/sda1.

    So it just takes a file and calculates an ID from which is known that another program using the same file and project ID will get the same result.

  4. key is just an identifier which is unique but can used for other purposes, while msqid is the ID (kind of handle) for a really existing queue.

glglgl
  • 89,107
  • 13
  • 149
  • 217