linux消息队列
创建
创建一个新的或打开一个已经存在的消息队列
int msgget(key_t key, int msgflg);
key:消息队列关联的键
msgflg:
IPC_CREAT如果内核中没有此队列,则创建
IPC_EXCL和IPC_CREAT一起使用时,如果队列已经存在,则创建失败
返回值:消息队列标识值
写入/读取
写入、读取消息队列
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
struct msgbuf
{
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
msgp:指向msgbuf的指针
msgtyp:消息类型
msgtyp等于0,返回队列的最早的一个消息
msgtyp大于0,返回其类型为mtype的第一个消息
msgtyp小于0,返回其类型小于或等于mtype参数的绝对值的最小的一个消息
msgflg:
IPC_NOWAIT,如果消息队列为空,则返回ENOMSG;如果不指定这个参数,那么进程将被阻塞直到函数可以从队列中得到符合条件的消息为止
MSG_EXCEPT,返回队列中第一个类型不为msgtyp的消息
MSG_NOERROR,如果函数取得的消息长度大于msgsz,将只返回msgsz 长度的信息,剩下的部分被丢弃了;如果不指定这个参数,E2BIG 将被返回,而消息则留在队列中不被取出
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
struct msqid_ds
{
struct ipc_perm msg_perm; /* Ownership and permissions */
time_t msg_stime; /* Time of last msgsnd(2) */
time_t msg_rtime; /* Time of last msgrcv(2) */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes in queue (nonstandard) */
msgqnum_t msg_qnum; /* Current number of messages in queue */
msglen_t msg_qbytes; /* Maximum number of bytes allowed in queue */
pid_t msg_lspid; /* PID of last msgsnd(2) */
pid_t msg_lrpid; /* PID of last msgrcv(2) */
};
struct ipc_perm
{
key_t __key; /* Key supplied to msgget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};
cmd:
IPC_STAT,读取消息队列的数据结构msqid_ds
IPC_SET,设置消息队列的数据结构msqid_ds
IPC_RMID,从系统内核中移除消息队列
举例
struct msgbuf
{
long mtype; /* message type, must be > 0 */
char mtext[1024]; /* message data */
};
int msqid = msgget((key_t)123, IPC_CREAT);
if(msqid < 0)
{
perror("msgget.");
return msqid;
}
struct msgbuf sbuf = {0};
sbuf.mtype = 1; //设置类型
char *text = "hello furong."; //填写数据
memcpy(sbuf.mtext, text, strlen(text));
if(fork() == 0)
{
while(1)
{
if(msgsnd(msqid, &sbuf, sizeof(struct msgbuf), IPC_NOWAIT) < 0)
{
perror("msgsnd.");
}
sleep(1);
}
}
struct msgbuf rbuf = {0};
while(1)
{
memset(&rbuf, 0, sizeof(rbuf));
if(msgrcv(msqid, &rbuf, sizeof(struct msgbuf), 0, 0) < 0)
{
perror("msgrcv.");
sleep(1);
}
puts(rbuf.mtext);
}
msgctl(msqid, IPC_RMID, 0);
命令
# ipcs -q //消息队列