代码改变世界

消息队列

2016-03-14 11:42  指针空间  阅读(845)  评论(0编辑  收藏  举报

消息队列允许一个或者多个进程向它写入与读取消息。Linux 维护着一个msgque 消息队列链表,其中每个元素指向一个描叙消息队列的msqid_ds 结构。当创建新的消息队列时,系统将从系统内存中分配一个msqid_ds 结构,同时将其插入到数组中。

  另外,Linux 保留有关队列修改时间信息,如上次系统向队列中写入的时间等。msqid_ds 包含两个等待队列:一个为队列写入进程使用而另一个由队列读取进程使用。由于Linux 严格限制可写入消息的个数和长度,队列中可能容纳不下这个消息。此时,此写入进程将被添加到这个消息队列的等待队列中,同时调用调度管理器选择新进程运行。当由消息从此队列中释放时,该进程将被唤醒。从队列中读的过程与此类似。

Msgreceive.c

#include <unistd.h> 

    #include <stdlib.h> 

    #include <stdio.h> 

    #include <string.h> 

    #include <errno.h> 

    #include <sys/msg.h> 

     

    struct msg_st 

    { 

        long int msg_type; 

        char text[BUFSIZ]; 

    }; 

     

    int main() 

    { 

        int running = 1; 

        int msgid = -1; 

        struct msg_st data; 

        long int msgtype = 2; //注意1 

           printf("hello\n");

        //建立消息队列 

        msgid = msgget((key_t)1234, 0666 | IPC_CREAT); 

        if(msgid == -1) 

        {

                   printf("1error\n");

            fprintf(stderr, "msgget failed with error: %d\n", errno); 

            exit(EXIT_FAILURE); 

        } 

        //从队列中获取消息,直到遇到end消息为止 

        while(running) 

        { 

            if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1) 

            { 

                   printf("2error\n");

                fprintf(stderr, "msgrcv failed with errno: %d\n", errno); 

                exit(EXIT_FAILURE); 

            } 

            printf("You wrote: %s\n",data.text); 

            //遇到end结束 

            if(strncmp(data.text, "end", 3) == 0) 

                running = 0; 

        } 

        //删除消息队列 

        if(msgctl(msgid, IPC_RMID, 0) == -1) 

        { 

            fprintf(stderr, "msgctl(IPC_RMID) failed\n"); 

            exit(EXIT_FAILURE); 

        } 

        exit(EXIT_SUCCESS); 

    }

 

 

Msgsend

 

#include <unistd.h> 

    #include <stdlib.h> 

    #include <stdio.h> 

    #include <string.h> 

    #include <sys/msg.h> 

    #include <errno.h> 

     

    #define MAX_TEXT 512 

    struct msg_st 

    { 

        long int msg_type; 

        char text[MAX_TEXT]; 

    }; 

     

    int main() 

    { 

        int running = 1; 

        struct msg_st data; 

        char buffer[BUFSIZ]; 

        int msgid = -1; 

     

        //建立消息队列 

        msgid = msgget((key_t)1234, 0666 | IPC_CREAT); 

        if(msgid == -1) 

        { 

            fprintf(stderr, "msgget failed with error: %d\n", errno); 

            exit(EXIT_FAILURE); 

        } 

     

        //向消息队列中写消息,直到写入end 

        while(running) 

        { 

            //输入数据 

            printf("Enter some text: "); 

            fgets(buffer, BUFSIZ, stdin); 

            data.msg_type = 2;    //注意2 

            strcpy(data.text, buffer); 

            //向队列发送数据 

            if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1) 

            { 

                fprintf(stderr, "msgsnd failed\n"); 

                exit(EXIT_FAILURE); 

            } 

            //输入end结束输入 

            if(strncmp(buffer, "end", 3) == 0) 

                running = 0; 

            sleep(1); 

        } 

        exit(EXIT_SUCCESS); 

    }