structmsqid_ds {structipc_permmsg_perm;/* Ownership and permissions */time_t msg_stime; /* Time of last msgsnd() */time_t msg_rtime; /* Time of last msgrcv() */time_t msg_ctime; /* Time of last change */unsignedlong __msg_cbytes; /* Number of bytes in queue */msgqnum_t msg_qnum; /* Number of messages in queue */msglen_t msg_qbytes; /* Maximum bytes in queue */pid_t msg_lspid; /* PID of last msgsnd() */pid_t msg_lrpid; /* PID of last msgrcv() */
};
消息队列的限制
MSGMNI:消息队列的数量
MSGMAX:单条消息最多可入字节数
MSGMNB:消息队列msg_qbytes最大值
MSGTQL:消息总数
MSGPOOL:消息队列数据缓冲池的大小
缺点
不是通过文件描述的引用,epoll等无法应用在消息队列上,如果代码里也是用文件描述符,会导致复杂
用键而不是文件名标识消息使设计复杂
消息队列无连接,内核对它没有引用计数
如何能够安全删除消息队列
如何确保消息队列不被删除
一般使用posix消息队列替代system v消息队列
更深一点使用基于多文件描述符的通信模型,ex:FIFO/SOCKET + epoll
linux/unix编程手册-47(System V 信号量)
信号量是用于同步进程动作,而不是进程间传递数据的
在一个信号量上的操作
将信号量设置成一个绝对值
当前值基础上加
当前值基础上减(可能阻塞,内核不允许信号量小于0)
等待信号量的值为0(可能阻塞)
创建或打开一个信号集
#include<sys/types.h>#include<sys/sem.h>intsemget(key_t key, int nsems, int semflg);
// nsems:信号集中信号量的数量
信号量的控制
#include<sys/types.h>#include<sys/sem.h>union semnum {
int val;
structsemid_dsbuf;unsignedshort * array;
#if defined(__linux__)structseminfo * __buf;#endif
};
intsemctl(int semid, int semnum, int cmd, .../* union semun arg */);
// semnum标明了集合的具体哪个信号量
cmd
IPC_RMID:删除
IPC_STAT:将semid_ds拷贝到arg.buf
IPC:SET:arg.buf替换
GETVAL:获取第semnum个信号量的值
SETVAL:将第semnum个信号量的值设为arg.val
GETALL:获取所有信号量的值放到arg.array指向的数组中
SETALL:获取所有信号量的值设置成arg.array指向的数组的值
GETPID:函数会返回上一个在该信号量上执行semop()进程的id,没有则0
GETNCNT:函数会返回等待该信号量值增长的进程数
GETNCNT:函数会返回等待该信号量值置为0的进程数
后面6个cmd在返回时可能已经过期
信号量关联数据结构
structsemid_ds {structipc_permsem_perm;/* Ownership and permissions */time_t sem_otime; /* Time of last semop() */time_t sem_ctime; /* Time of last change */unsignedlong sem_nsems; /* Number of semaphores in set */
};
#include<sys/types.h>#include<sys/shm.h>intshmctl(int shmid, int cmd, struct shmid_ds *buf);
类似前两个
共享内存关联数据结构
structshmid_ds {structipc_permshm_perm;/* Ownership and permissions */size_t shm_segsz; /* Size of segment in bytes */time_t shm_atime; /* Time of last shmat() */time_t shm_dtime; /* Time of last shmdt() */time_t shm_ctime; /* Time of last change */pid_t shm_cpid; /* PID of creator */pid_t shm_lpid; /* PID of last shmat() / shmdt() */shmatt_t shm_nattch; /* Number of currently attached processes */
};