1. 问题
探究下Key和identifier的关系?
2. 论证资料
2.1 以下引用来自science
Processes may access these resources only by passing a unique reference identifier to the kernel via system calls. The object’s reference identifier is used by each mechanism as an index into a table of resources. It is not a straight forward index but requires some manipulation to generate the index.
The key is used as a way of locating the System V IPC object’s reference identifier. Two sets of key are supported: public and private. If the key is public then any process in the system, subject to rights checking, can find the reference identifier for the System V IPC object. System V IPC objects can never be referenced with a key, only by their reference identifier.
进程需要相应的indentifier
来访问相应的IPC
,且这是唯一手段!key
的作用可以用来生产indentifier
或者引用相应的indentifier
。当key
是私有属性的时候,其只能被用来生成indentifier
。最后一句话很重要:Key不能用来直接引用IPC object
!
2.2 以下引用来自APUE
Each IPC structure (message queue, semaphore, or shared memory segment) in the kernel is referred to by a non-negative integer identifier. To send a message to or fetch a message from a message queue, for example, all we need know is the identifier for the queue.
The identifier is an internal name for an IPC object. Cooperating processes need an external naming scheme to be able to rendezvous using the same IPC object. For this purpose, an IPC object is associated with a key that acts as an external name.
实际上就是这句话比较难以理解,因为internal name
和external naming scheme
可能会混淆很多概念,但是如果读到下面的话,再结合上面就比较容易理解了:
- The server can create a new IPC structure by specifying a key of IPC_PRIVATE and store the returned identifier somewhere (such as a file) for the client to obtain. The key IPC_PRIVATE guarantees that the server creates a new IPC structure. The IPC_PRIVATE key is also used in a parent–child relationship. The parent creates a new IPC structure specifying IPC_PRIVATE, and the resulting identifier is then available to the child after the fork. The child can pass the identifier to a new program as an argument to one of the exec functions.
- The client and the server can agree on a key by defining the key in a common header, for example.
- The server then creates a new IPC structure specifying this key. The client and the server can agree on a pathname and project ID (the project ID is a character value between 0 and 255) and call the function ftok to convert these two values into a key.
有上述三种使用IPC
进行沟通的方式,第一种直接使用identifer
,第二种只使用key
,第三种生成key
之后再使用它。但是因为identifier
是IPC object
的内部名称,所以后续IPC
的API接口都是基于该identifier
,而key
只是用来生成identifier
或者得到已存在IPC
的identifier
,最后用一句话来说:identifier
是访问IPC的直接手段,可以通过key
间接访问IPC
,但是还是通过key
得到相应的identifier
来访问。以下两段引用可以证明笔者的结论:
- Whenever an IPC structure is being created (by calling msgget, semget, or shmget), a key must be specified. This key is converted into an identifier by the kernel.
- To reference an existing queue that was created with a key of IPC_PRIVATE, we must know the associated identifier and then use that identifier in the other IPC calls (such as msgsnd and msgrcv), bypassing the get function.
2.3 以下引用来自The Linux Programming Interface
- An IPC identifier is analogous to a file descriptor in that it is used in all subsequent system calls to refer to the IPC object. All processes accessing the same object use the same identifier.
- System V IPC keys are integer values represented using the data type key_t. The IPC get calls translate a key into the corresponding integer IPC identifier. These calls guarantee that if we create a new IPC object, then that object will have a unique identifier, and that if we specify the key of an existing object, then we’ll always obtain the (same) identifier for that object. (Internally, the kernel maintains data structures mapping keys to identifiers for each IPC mechanism)
总结上面的引用:identifier
类比于fd
,之后所有的进程可用通过该identifier
访问一个IPC object
。可以通过key
来生成一个identifier
,此时该identifier
可能是新创建的,也可能是已经存在的,取决于相应get系列API的使用方式。
3. 结论
所以回到问题上来,它们的关系就是甲鱼的屁股。API接口规定就是这么用的:简单记住identifier
是访问IPC
的唯一途径,但是可以通过Key
生成identifier
。比较有趣的是,笔者找到一个和笔者观点一致的答案在Stackoverflow: