程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 一起talk C栗子吧(第九十七回:C語言實例--使用消息隊列進行進程間通信一)

一起talk C栗子吧(第九十七回:C語言實例--使用消息隊列進行進程間通信一)

編輯:關於C語言

一起talk C栗子吧(第九十七回:C語言實例--使用消息隊列進行進程間通信一)



各位看官們,大家好,上一回中咱們說的是使用共享內存進行進程間通信的例子,這一回咱們說的例子是:使用消息隊列進行進程間通信。閒話休提,言歸正轉。讓我們一起talk C栗子吧!

消息隊列是SystemV IPC結構這種抽象概念的一種具體對象,這點和共享內存一樣。消息隊列提供了一個隊列供不同的進程使用,進程之間可以通過該隊列傳遞數據,進而實現進程間的通信。

在介紹消息隊列的使用方法之前,我們先介紹幾個函數,這些函數都是用來操作消息隊列的。

msgget函數

int msgget(key_t key,int msgflag)

該函數用來創建一個新的消息隊列或者獲取已經存在的消息隊列。

第一個參數是鍵值,通過它來操作IPC在內核中的結構,也就是消息隊列在內核中的結構;(前面章回中介紹過) 第二個參數是消息隊列的權限標記,該權限和文件權限一樣; 該函數運行成功時返回消息隊列標識符,否則返回-1;我們可以通過該標識符使用消息隊列;

msgsnd函數

int msgsnd(int msg_id, const void *msg_ptr,size_t msg_sz,int msgflg)

該函數用來把消息添加到消息隊列中,這樣進程就可以從消息隊列中獲取消息了;

在使用該函數的時候,我們需要自己定義一個消息的類型,並且計算出該類型的內存空間。消息的類型可以依據程序需要來定義,常見的是定義一個結構體類型。不過類型中的第一個成員必須是一個long int類型的成員,該成員用來確定消息的類型。

第一個參數是消息隊列的標識符,通過msgget函數可以獲得; 第二個參數是一個指針,該指針指向准備添加到消息隊列中消息; 第三個參數是一個int類型的值,表示准備添加到消息隊列中消息的大小; 第四個參數是一個位標記,該標記用來控制消息隊列已滿或者達到系統限制時的動作。 該函數運行成功時返回0,否則返回-1;

在使用該函數的時候,第四個參數通常為IPC_NOWAIT,表示消息隊列已滿後函數不發消息到消息隊列中,並且立刻返回-1.如果沒有設置該標記,那麼消息隊列已滿後先把以送消息的進程掛起,直到消息到消息隊列中有空間了,它再發送消息到消息隊列中。

msgrcv函數

int msgrcv(int msgid,void *msg_ptr,size_t msg_sz,long int msgtype,int msgflg)

該函數用來從消息隊列中獲取消息或者說接收消息;

第一個參數是消息隊列的標識符,通過msgget函數可以獲得; 第二個參數是一個指針,該指針指向准備從消息隊列中獲取的消息; 第三個參數是一個int類型的值,表示獲取消息的大小; 第四個參數是一個long int類型的值,表示接收消息的優先級; 第五個參數是一個位標記,該標記用來控制消息隊列中沒有消息供接收時的動作。 該函數運行成功時返回接收到消息的字節數,否則返回-1;

在使用該函數數,第五個參數的值和msgsnd函數中第四個參數的值一樣,而且函數的動作也類似,只不過從發送消息轉換為接收消息。該函數的第四個參數通常為0,表示按照消息的發送順序接收消息;
如果它的值為n(n>0),表示接收類型值為n的這一類消息;
如果它的值為-n(n>0),表示接收類型值為等於或者小於n的這一類消息;
這裡說的類型值就是我們定義消息類型中的第一個成員。

msgctl函數

int msgctl(int msg_id, int cmd,struct msgid_ds *buf)

該函數用來對消息隊列進行相關操作,常用的操作是刪除消息隊列;

第一個參數是消息隊列的標識符,通過msgget函數可以獲得; 第二個參數是一個命令,表示對消息隊列的操作,只有三個命令供使用:IPC_STAT,IPC_SET和IPC_RMID; 第三個參數是一個結構體指針,該結構體中有消息隊列的權限和所有者等信息; 該函數運行成功時返回0,否則返回-1;

我們通常使用該函數刪除消息隊列,這時候需要給第二個參數賦值為IPC_RMID,表示刪除消息隊列,第三參數可以為空指針。第二個參數的另外兩個命令:IPC_STAT表示把第三個參數中的內容和消息隊列關聯起來;IPC_SET表示把第三個參數中的內容設置為消息隊列的值。第三個參數的類型,我們在前面章回中提起過,它和SystemV IPC的結構類似,除了必須有的成員外,它還有自己特有的成員。

該函數的用法和咱們在前面章回中介紹過的shmctl函數用法類似,大家可以進行對比。

我從源代碼中找到了第三個參數的類型,詳細的定義如下:(位於linux-4.0.3/include/linux/msg.h文件中)

struct msg_queue {
    struct kern_ipc_perm q_perm;
    time_t q_stime;         /* last msgsnd time */
    time_t q_rtime;         /* last msgrcv time */
    time_t q_ctime;         /* last change time */
    unsigned long q_cbytes;     /* current number of bytes on queue */
    unsigned long q_qnum;       /* number of messages in queue */
    unsigned long q_qbytes;     /* max number of bytes on queue */
    pid_t q_lspid;          /* pid of last msgsnd */
    pid_t q_lrpid;          /* last receive pid */

    struct list_head q_messages;
    struct list_head q_receivers;
    struct list_head q_senders;
};

各位看官,關於使用消息隊列進行進程間通信的例子咱們就說到這裡。欲知後面還有什麼例子,且聽下回分解 。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved