3
votes

In system V message queues, We get a message queue identifier using the msgget() system call

int msqid = msgget(key, 0666 | IPC_CREAT);

If msqid is the unique queue identifer, then what is the key? Isn't it also a unique queue identifier?

All that man page says is this

The msgget() system call returns the System V message queue identifier associated with the value of the key argument

There is no explanation of what that key actually is. Is it a key for some sort of hash table where the value is a bunch of IPC tools? I've read this post but it's still muddy.

Also people generally use ftok() to generate a key.

key_t ftok(const char *pathname, int proj_id); 

The ftok() function uses the identity of the file named by the given pathname (which must refer to an existing, accessible file) and the least significant 8 bits of proj_id (which must be nonzero) to generate a key_t type System V IPC key

Why would anyone want to generate a unique number by hashing the inode of a file? Personally I think that all processes agreeing to a common number is easier to implement than all processes agreeing to a common file. Is it solely for uniform distribution purposes as this answer states?

2
"If msqid is the unique queue identifer, then what is the key? Isn't it also a unique queue identifier?". msqid is unique only within the process. key is globally unique.kaylum

2 Answers

0
votes

Neither agreeing to a fixed number nor agreeing to a fixed file is practical because of collisions. The namespace of keys is tiny and system-global. In practice you have to generate keys randomly (retrying with a new random value if the key already exists) and communicate the key via another channel (like storing it in a file or passing it on the command line or in some kind of message).

0
votes

msqid is the unique queue identifer to be used as reference in your program to identify that queue. You need that identifier because later you might want to use msgsend to actually send a message to that queue. And that requires the queue identifier as argument.

The key is the system-wide reference for that particular queue. An analogy would be to consider it like a TCP or UDP port number (which is also "system-wide" -at least for a specific IP-).

ftok is just a convenient way of using a common file across an entire distributed application with proj-id being the queues associated to that application. By using ftok you mitigate -but do not fully avoid- the chances of collisions and you simplify the selection of key values across applications. Imagine an application that uses 10 message queues, you just designate a file for the whole application and use proj_id numbers from 1 to 10. Other application could designate a different file and use the same proj_id 1 to 10 numbers "without collisions" (read next paragraph to clarify that the solution can present collisions).

As mentioned in several comments the solution is prone to collisions- But for some applications this might not be an issue, specially in custom applications intended to run in controlled environments where your application(s) is(are) the only one(s) using message queues and keys can be assigned on a system-wide basis.

It can be compared with deploying two applications listening at UDP port 10000 in the same interface. They can not and the ports need to be assigned on a system-wide basis.

The message queues were incorporated to UNIX System V Release 2 around 1984 by the AT&T. It is a basic solution, but for its time, it probably has some virtues.

Same as other System V IPC mechanisms, they are old solutions that can be still applied as long as you find them useful for your application and the caveats and limitations are understood and do not represent any issue.