今天来聊聊用户态System V ipc,也就是常说的信号量、消息队列以及共享内存,以信号量为例
内核当中信号量的数据结构,跟命名空间是相关的,给定的进程属于task_struct->nsproxy->ipc_ns指向的命名空间,ipc_namespace结构如下:
-
struct ipc_namespace {
-
refcount_t count;
-
struct ipc_ids ids[3];
-
...
-
};
其中,数组ids当中的每个ipc_ids分别代表当前ipc命名空间下的三种ipc机制0-信号量,1-消息队列,2-共享内存
-
struct ipc_ids {
-
int in_use;
-
unsigned short seq;
-
struct rw_semaphore rwsem;
-
struct idr ipcs_idr;
-
int max_idx;
-
int last_idx; /* For wrap around detection */
-
#ifdef CONFIG_CHECKPOINT_RESTORE
-
int next_id;
-
#endif
-
struct rhashtable key_ht;
-
};
其中,ipcs_idr是将当前类型的ipc的id映射到对应的内核数据结构kern_ipc_perm的基数树,
-
struct kern_ipc_perm {
-
spinlock_t lock;
-
bool deleted;
-
int id;
-
key_t key;
-
kuid_t uid;
-
kgid_t gid;
-
kuid_t cuid;
-
kgid_t cgid;
-
umode_t mode;
-
unsigned long seq;
-
void *security;
-
-
struct rhash_head khtnode;
-
-
struct rcu_head rcu;
-
refcount_t refcount;
-
};
三种ipc在内核当中的表示的第一个元素,都是kern_ipc_perm,当通过基数树找到对应的kern_ipc_perm的指针时候,直接强转就ok了。比如信号量:
-
struct sem_array {
-
struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */
-
time64_t sem_ctime; /* create/last semctl() time */
-
struct list_head pending_alter; /* pending operations */
-
/* that alter the array */
-
struct list_head pending_const; /* pending complex operations */
-
/* that do not alter semvals */
-
struct list_head list_id; /* undo requests on this array */
-
int sem_nsems; /* no. of semaphores in array */
-
int complex_count; /* pending complex operations */
-
unsigned int use_global_lock;/* >0: global lock required */
-
-
struct sem sems[];
-
};
sem_nsems表示当前信号量集合包含信号量的数目,以及在当前信号量上挂着的队列
-
struct sem_queue {
-
struct list_head list; /* queue of pending operations */
-
struct task_struct *sleeper; /* this process */
-
struct sem_undo *undo; /* undo structure */
-
struct pid *pid; /* process id of requesting process */
-
int status; /* completion status of operation */
-
struct sembuf *sops; /* array of pending operations */
-
struct sembuf *blocking; /* the operation that blocked */
-
int nsops; /* number of operations */
-
bool alter; /* does *sops alter the array? */
-
bool dupsop; /* sops on more than one sem_num */
-
};
如果内核配置了CONFIG_DETECT_HUNG_TASK,task_struct里面才会有ipc相关成员
-
struct task_struct{
-
...
-
#ifdef CONFIG_SYSVIPC
-
struct sysv_sem sysvsem;
-
struct sysv_shm sysvshm;
-
#endif
-
...
-
};
其中,这俩都是用于当前程序崩溃时,释放相关资源的链表
-
struct sysv_sem {
-
struct sem_undo_list *undo_list;
-
};
阅读(1599) | 评论(0) | 转发(0) |