linux共用記憶體實驗

來源:互聯網
上載者:User

    顧名思義,訊息佇列就是一些訊息的列表,使用者可以在訊息佇列中添加訊息和讀取訊息等。從這點上看,訊息佇列具有一定的FIFO特性,但是它可以實現訊息的隨機查詢,比FIFO具有更大的優勢。同時,這些訊息又是存在於核心中的,由“隊列ID”來標識。

    訊息佇列的實現包括建立或開啟訊息佇列、添加訊息、讀取訊息和控制訊息隊列4種操作,其中建立或開啟訊息佇列使用的函數是msgget(),這裡建立的訊息佇列的數量會受到系統訊息佇列數量的限制;添加訊息使用的函數是msgsnd(),它把訊息添加到已開啟的訊息佇列末尾;讀取訊息使用的函數是msgrcv(),它把訊息從訊息佇列中取走,與FIFO不同的是,這裡可以取走指定的某一條訊息;控制訊息隊列使用的函數是msgctl(),它可以完成多項功能。

    表1列舉了msgget()函數的文法要點。

表1 msgget()函數文法要點


#include <sys/ipc.h> #include <sys/shm.h>

    表2列舉了msgsnd()函數的文法要點。

表2 msgsnd()函數文法要點






#include <sys/ipc.h> #include <sys/shm.h> struct msgbuf {   long mtype; /* 訊息類型,該結構必須從這個域開始 */   char mtext[1]; /* 訊息本文 */ }

    表3列舉了msgrcv()函數的文法要點。

表3 msgrcv()函數文法要點


#include <sys/ipc.h> #include <sys/shm.h>

    表4列舉了msgctl()函數的文法要點。

表4 msgctl()函數文法要點


#include <sys/ipc.h> #include <sys/shm.h>

    下面的執行個體體現了如何使用訊息佇列進行兩個進程(發送端和接收端)之間的通訊,包括訊息佇列的建立、訊息發送與讀取、訊息佇列的撤銷和刪除等多種操作。

    訊息發送端進程和訊息接收端進程間不需要額外實現進程間的同步。在該執行個體中,發送端發送的訊息類型設定為該進程的進程號(可以取其他值),因此接收端根據訊息類型來確定訊息寄件者的進程號。注意這裡使用了fotk()函數,它可以根據不同的路徑和關鍵字產生標準的key。訊息佇列發送端的代碼如下:

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #define BUFFER_SIZE512


    struct message
    {
        long msg_type;
        char msg_text[BUFFER_SIZE];
    };
    int main()
    {
        int qid;
        key_t key;
        struct message msg;

        /* 根據不同的路徑和關鍵字產生標準的key */
        if ((key = ftok(".", 'a')) == -1)
        {
            perror("ftok");
            exit(1);
        }
        /* 建立訊息佇列 */
        if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
        {
            perror("msgget");
            exit(1);
        }
        printf("Open queue %d\n",qid);
        while(1)
        {
            printf("Enter some message to the queue:");
            if ((fgets(msg.msg_text, BUFFER_SIZE, stdin)) == NULL)
            {
                puts("no message");
                exit(1);
            }

            msg.msg_type = getpid();
            /* 添加訊息到訊息佇列 */
            if ((msgsnd(qid, &msg, strlen(msg.msg_text), 0)) < 0)
            {
                perror("message posted");
                exit(1);
            }
            if (strncmp(msg.msg_text, "quit", 4) == 0)
            {
                break;
            }
        }
        exit(0);
    }

    訊息佇列接收端的代碼如下:

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #define BUFFER_SIZE512

    struct message
    {
        long msg_type;
        char msg_text[BUFFER_SIZE];
    };
    int main()
    {
        int qid;
        key_t key;
        struct message msg;

        /* 根據不同的路徑和關鍵字產生標準的key */
        if ((key = ftok(".", 'a')) == -1)
        {
            perror("ftok");
            exit(1);
        }
        /* 建立訊息佇列 */
        if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
        {
            perror("msgget");
            exit(1);
        }
        printf("Open queue %d\n", qid);
        do
        {
            /* 讀取訊息佇列 */
            memset(msg.msg_text, 0, BUFFER_SIZE);
            if (msgrcv(qid, (void*)&msg, BUFFER_SIZE, 0, 0) < 0)
            {
                perror("msgrcv");
                exit(1);
            }
            printf("The message from process %d : %s", msg.msg_type, msg.msg_text);

        } while(strncmp(msg.msg_text, "quit", 4));
        /* 從系統核心中移走訊息佇列 */
        if ((msgctl(qid, IPC_RMID, NULL)) < 0)
        {
            perror("msgctl");
            exit(1);
        }
        exit(0);
    }

    以下是程式的運行結果,輸入“quit”則兩個進程都將結束。

    Open queue 327680
    Enter some message to the queue:first message
    Enter some message to the queue:second message
    Enter some message to the queue:quit
    $ ./msgrcv
    Open queue 327680
    The message from process 6072 : first message
    The message from process 6072 : second message
    The message from process 6072 : quit

    本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程式開發》

    更多嵌入式電子書查看華清遠見電子書頻道>>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.