进程通讯中的消息队列

1、消息队列是什么?
    消息队列是在内核空间内部的一个链表。通过Linux内核在各个进程间传递消息。
    要获取对应的消息队列,每一个消息队列都有一个唯一的表示符来区分。

2、怎么样使用消息队列进行进程间通讯?
    
    1)先产生一个标示符
           #include <sys/types.h>
           #include <sys/ipc.h>

            key_t ftok(const char *pathname, int proj_id);
                    pathname  :这个路径必须是一个存在的、可访问的的文件
                    proj_id :必须是一个非零的数字,然后通过这个函数就会产生一个key_t类型的标示符。

            返回值:成功就会返回 对应的key值,错误返回-1,并且可以把对应的错误码打印出来看一下是什么错误。

    2)通过这个key去创建消息队列
            #include <sys/types.h>
            #include <sys/ipc.h>
            #include <sys/msg.h>

            int msgget(key_t key, int msgflg);
            第一个参数,第一个参数就是我们第一步通过ftok产生的key值,用来标识唯一的消息队列。
            第二个参数,分为有两种
                第一种情况:创建  IPC_CREAT | 权限位  例如: IPC_CREAT | 0664 
                第二种情况:打开 0 
        
            返回值:成功返回的是消息队列的ID,如果失败了,返回-1,并且错误码可以通过perror打印出来。


    3)通过收发的函数,实现收发,实现进程间通讯。

       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
                    msqid:这个参数就是消息队列的ID,表示我们要把消息发送到哪个队列,或者从哪个队列来接受消息。
                    msgp:这个是指针,指向我们所需要发送的消息,消息我们可以自定义。
                   struct msgbuf {
                           long mtype;       /* message type, must be > 0  消息的类型,这个参数是自己定义 */
                          char mtext[1];    /* message data  这个是我们需要发送的消息的具体数据 */
                       };
                    msgsz :消息内容的长度,是对应mtext的实际大小。
                    msgflg:
                        1)IPC_NOWAIT 不阻塞的模式。
                        2)0 阻塞模式发送(一般都是用这个)

        返回值:成功返回0,失败的话返回-1,并且可以把对应的错误码打印出来。
        

       ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
       这个函数的作用,就是在指定的消息队列里面,把消息摘下来,拷贝到msgp所指定buffer里面。
                    msqid:这个参数就是消息队列的ID,表示我们要把消息发送到哪个队列,或者从哪个队列来接受消息。
                    msgp:这个是指针,指向我们所需要接收的消息的buffer,
                    msgsz:指的是消息的最大的长度,消息内容的长度,是对应mtext的实际大小。
                    msgtyp:指的是消息的类型,0代表读取的是队列内第一个消息。如果是大于零的时候,队列里面第一个msgtyp类型的消息就会被读回来。
                    msgflg:
                        1)IPC_NOWAIT 不阻塞的模式。
                        2)0 阻塞模式发送(一般都是用这个)

        返回值:成功的话,返回的是,对应mtext的实际大小(实际消息的长度), 失败的话返回-1,并且可以把对应的错误码打印出来。


    4)用于控制这个消息队列,比如说删除队列。

    int msgctl(int msqid, int cmd, struct msqid_ds *buf);
        msqid:这个参数就是消息队列的ID
        cmd: 一些命令,常用的有删除队列的命令:IPC_RMID
        msqid_ds *buf ,关于队列的一些信息的描述。

今日程序:

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<string.h>
struct msgbuf
{
    long mytype;
    char mtext[256];
};

int main()
{
    int msgid;
    key_t key;
    struct msgbuf msg,msgr;

    key = ftok("/home/gec",111);
    if(key < 0)
    {
        perror("ftok fail\n");
        exit(-1);
    }
    printf("key = %d\n",key);

    msgid = msgget(key,IPC_CREAT|0777);
    if(msgid < 0)
    {
        perror("msgget fail");
        exit(-1);
    }

    msg.mytype = 888;
            
    while(1)
    {
        printf("A说:");
        memset(msg.mtext,0,strlen(msg.mtext));
        scanf("%s",msg.mtext);
        msgsnd(msgid,&msg,256,0);
        
        msgrcv(msgid,&msgr,256,888,0);
        printf("B回应说:%s\n",msgr.mtext);        
    }
    return 0;
}

/////////////////////////////////////////////////////////////////

#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<string.h>

struct msgbuf
{
    long mytype;
    char mtext[256];
};

int main()
{
    int msgid;
    key_t key;
    struct msgbuf msg,msgr;

    key = ftok("/home/gec",111);
    if(key < 0)
    {
        perror("ftok fail\n");
        exit(-1);
    }
    printf("key = %d\n",key);

    msgid = msgget(key,IPC_CREAT|0777);
    if(msgid < 0)
    {
        perror("msgget fail");
        exit(-1);
    }

    msg.mytype = 888;

    while(1)
    {
        msgrcv(msgid,&msg,256,888,0);
        printf("A回应说:%s\n",msgr.mtext);

        printf("B说:");
        memset(msgr.mtext,0,strlen(msgr.mtext));
        scanf("%s",msgr.mtext);
        msgsnd(msgid,&msg,256,0);
    }
    return 0;
}
 

猜你喜欢

转载自blog.csdn.net/qq_37589838/article/details/81209068