消息队列:

1》创建新消息队列或取得已存在消息队列---msgget

#include <sys / types.h>

#include <sys / ipc.h>

#include <sys / msg.h>

int msgget(key_t key, int msgflg);

参数

key:键值。

msgflg:IPC_CREAT|0666值,若没有该队列,则创建一个并返回新标识符;若已存在,则返回原标识符。

 返回值:成功执行时,返回消息队列标识值。失败返回-1;

eg:

int key=ftok();
int msgid=msgget(key,IPC_CREAT);
if(msgid==-1)
{
  perror(msgget);
  return -1;
}

2》添加消息队列(发送)---msgsnd

把消息添加到已打开的消息队列末尾

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

参数

msgid:指明消息队列的 ID,通常是 msgget 函数成功的返回值

msgp:发送数据缓冲区首地址

msgp:指向消息结构的指针。该消息结构 msgbuf 为:

struct msgbuf{

long mtype;//消息类型

char mtext[1];//消息正文 可以任意类型

}

msgsz:要发送的数据大小,上一个参数的大小减去sizeof(long),每个消息体最大不要超过

msgflg:一般赋0,阻塞方式;

返回值:成功则返回0, 出错则返回-1

struct msgbuf{

long type;

char buf[32];

};

struct msgbuf s = {111,”liming”}

msgsnd(msgid,&s,)

3》读取消息(接收)   ---msgrcv   

把消息从消息队列中取走,与 FIFO不同的是,这里可以指定取走某种type的消息

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

    参数

        msqid:消息队列的队列

        msgp:消息缓冲区

        size:消息的字节数

        msgtyp:消息类型 

=0 忽略类型  

>0 只接收指定类型的数据 

<0 只接受小于等于其绝对值的数据

msgflg:0  -- 阻塞

    返回值

        接收成功返回0,失败返回-1

4》控制消息队列-- msgctl

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

    参数

        msqid:消息队列的队列

        cmd

          IPC_STAT:读取消息队列的数据结构 msqid_ds,并将其存储在buf 指定的地址中

          IPC_SET:设置消息队列的数据结构 msqid_ds 中的 ipc_perm 元素的值。这个值取自 buf 参数

          IPC_RMID:从系统内核中删除消息队列,最后一个参数填写NULL;

        Buf:消息队列缓冲区

    返回值

        接收成功返回0,失败返回-1

例题:实现收发打印出来(创建fork)

//--------------------------发
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf{
long type;//消息类型
char name[16];//消息正文 可以任意类型
};
int main()
{
    int key=ftok("/home/fuc/test/2_23",11);
    int msgid=msgget(key,IPC_CREAT|0666);//创建消息队列
    struct msgbuf m1={111,"小红"};
    struct msgbuf m2={111,"奥德彪"};
    struct msgbuf m3={222,"翠芬"};
    //写入消息队列
    msgsnd(msgid,&m1,sizeof(m1)-sizeof(long),0);
    msgsnd(msgid,&m2,sizeof(m2)-sizeof(long),0);
    msgsnd(msgid,&m3,sizeof(m3)-sizeof(long),0);
    return 0;
}
//--------------------------收
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <errno.h>
#include <wait.h>
struct msgbuf{
long type;//消息类型
char name[16];//消息正文 可以任意类型
};
int main()
{
    int key=ftok("/home/fuc/test/2_23",11);
    int msgid=msgget(key,IPC_CREAT|0666);//打开消息队列
    //写入消息队列
    struct msgbuf m1;
    pid_t pid=fork();
    if(pid>0)
    {
        while(1)
        {
            wait(NULL);
            int a=msgrcv(msgid,&m1,sizeof(m1)-sizeof(long),111,IPC_NOWAIT);
            
             if((a==-1)&&(errno==ENOMSG))
            {
                break;
            }
            printf("father:%s\n",m1.name);
        }
    }
    if(pid==0)
    {
        while(1)
        {
            int a=msgrcv(msgid,&m1,sizeof(m1)-sizeof(long),222,IPC_NOWAIT);
            
            if((a==-1)&&(errno==ENOMSG))
            {
                break;
            }
            printf("son:%s\n",m1.name);
        }
    }
   
    
  
    return 0;
}