请你说一说消息队列、信号量的实现方式
参考回答:
struct msgid_ds { struct ipc_perm msg_perm; msgqnum_t msg_qnum; /* # of messages on queue */ msglen_t msg_qbytes; /* max # of bytes on queue */ pid_t msg_lspid; /* pid of last msgsnd() */ pid_t msg_lrpid; /* pid of last msgrcv() */ time_t msg_stime; /* last-msgsnd() time */ time_t msg_rtime; /* last-msgrcv() time */ time_t msg_ctime; /* last-change time */ ... };
此结构定义了队列的当前状态。msgget用于创建一个新队列或打开一个现有队列,msgsnd将消息添加到队列的尾端(每个消息包括一个长整型类型字段,一个非负的长度,实际的数据长度),msgrcv用于从队列中取消息(并不一定要以先进先出次序取消息,可以按消息的类型字段取消息)。
信号量是一个计数器,用于为多个进程提供对共享对象的访问。为了正确地实现信号量,信号量的测试及加减1操作应当是原子操作,为此,信号量通常是在内核中实现的。
常用的信号形式是二元信号量(binary semaphore)。它控制单个资源,其初始值为1。但是,一般而言,信号量的初值也可以是任意一个正值,表明有多少个共享单位可供共享。
内核为每个信号量集合维护着一个semid_ds结构:
struct semid_ds { struct ipc_perm sem_perm; unsigned short sem_nsems; /* # of semaphores in set */ time_t sem_otime; /* last-semop() time */ time_t sem_ctime; /* last-change time */ ... };
每个信号量由一个无名结构体表示,至少包含下列成员:
struct { unsigned short semval; /* semaphore value, always >= 0 */ pid_t sempid; /* pid for last operation */ unsigned short semncnt; /* # processes awaiting semval > curval */ unsigned short semzcnt; /* # processes awaiting semval == 0 */ ... };