IPC(Interprocess Communication)表示进程间通信机制;System V IPC机制主要有消息队列、共享内存、信号量,linux中实现了SysV IPC。
I.SysV IPC创建/获取
消息队列、共享内存、信号量的创建/获取API原型如下:
int msgget(key_t key, int msgflg);
int shmget(key_t key, size_t size, int shmflg);
int semget(key_t key, int nsems, int semflg);
以上API主要用来创建新的IPC或根据key值查找IPC,并返回IPC id;内核实现均调用ipcget:
ipc/util.c:
734 /**
735 * ipcget - Common sys_*get() code
736 * @ns : namsepace
737 * @ids : IPC identifier set
738 * @ops : operations to be called on ipc object creation, permission checks
739 * and further checks
740 * @params : the parameters needed by the previous operations.
741 *
742 * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
743 */
744 int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
745 struct ipc_ops *ops, struct ipc_params *params)
746 {
747 if (params->key == IPC_PRIVATE)
748 return ipcget_new(ns, ids, ops, params);
749 else
750 return ipcget_public(ns, ids, ops, params);
751 }
i.key
key类型为key_t,即int:
/usr/include/bits/types.h:101:#define __S32_TYPE int
/usr/include/bits/typesizes.h:55:#define __KEY_T_TYPE __S32_TYPE
/usr/include/bits/types.h:155:__STD_TYPE __KEY_T_TYPE __key_t; /* Type of an IPC key. */
/usr/include/sys/ipc.h:48:typedef __key_t key_t;
SysV IPC均用key值作为主键,系统级标识出IPC;同时每一个IPC都有一个id与之对应。
key和id都能标识出IPC,区别主要是,key由用户程序提供,以便用户程序标识IPC实现进程间通信;id由系统返回,能快速查找到IPC并使用。
key查找IPC过程:遍历IPC id基数树的叶子结点,找出key对应的IPC。实现为ipc_findkey:
170 /**
171 * ipc_findkey - find a key in an ipc identifier set
172 * @ids: Identifier set
173 * @key: The key to find
174 *
175 * Requires ipc_ids.rw_mutex locked.
176 * Returns the LOCKED pointer to the ipc structure if found or NULL
177 * if not.
178 * If key is found ipc points to the owning ipc structure
179 */
180
181 static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
182 {
183 struct kern_ipc_perm *ipc;
184 int next_id;
185 int total;
186
187 for (total = 0, next_id = 0; total < ids->in_use; next_id++) {
188 ipc = idr_find(&ids->ipcs_idr, next_id);
189
190 if (ipc == NULL)
191 continue;
192
193 if (ipc->key != key) {
194