Linux 程序間通訊之訊息佇列

2021-09-11 10:23:38 字數 3517 閱讀 4039

**:

訊息佇列

一. 什麼是訊息佇列?

訊息佇列是訊息的鍊錶,存放在核心中並由訊息佇列識別符號表示。 

訊息佇列提供了乙個從乙個程序向另乙個程序傳送資料塊的方法,每個資料塊都可以被認為是有乙個型別,接受者接受的資料塊可以有不同的型別。 

但是同管道類似,它有乙個不足就是每個訊息的最大長度是有上限的(msgmax),每個訊息佇列的總的位元組數(msgmnb),系統上訊息佇列的總數上限(msgmni)。可以用cat /proc/sys/kernel/msgmax檢視具體的資料。 

核心為每個ipc物件維護了乙個資料結構struct ipc_perm,用於標識訊息佇列,讓程序知道當前操作的是哪個訊息佇列。每乙個msqid_ds表示乙個訊息佇列,並通過msqid_ds.msg_first、msg_last維護乙個先進先出的msg鍊錶佇列,當傳送乙個訊息到該訊息佇列時,把傳送的訊息構造成乙個msg的結構物件,並新增到msqid_ds.msg_first、msg_last維護的鍊錶佇列。在核心中的表示如下: 

二. 特點:

生命週期隨核心,訊息佇列會一直存在,需要我們顯示的呼叫介面刪除或使用命令刪除

訊息佇列可以雙向通訊

克服了管道只能承載無格式位元組流的缺點

三. 訊息佇列函式

1.msgget

功能:建立和訪問乙個訊息佇列 

原型:#include

#include

#include

int msgget(key_t key, int msgflag);

引數: 

key:某個訊息佇列的名字,用ftok()產生 

msgflag:有兩個選項ipc_creat和ipc_excl,單獨使用ipc_creat,如果訊息佇列不存在則建立之,如果存在則開啟返回;單獨使用ipc_excl是沒有意義的;兩個同時使用,如果訊息佇列不存在則建立之,如果存在則出錯返回。 

返回值:成功返回乙個非負整數,即訊息佇列的標識碼,失敗返回-1

#include

#include

key_t ftok(const char *pathname, int proj_id);

呼叫成功返回乙個key值,用於建立訊息佇列,如果失敗,返回-1

2.msgctl

功能:訊息佇列的控制函式 

原型:#include

#include

#include

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

引數: 

msqid:由msgget函式返回的訊息佇列標識碼 

cmd:有三個可選的值,在此我們使用ipc_rmid

ipc_stat 把msqid_ds結構中的資料設定為訊息佇列的當前關聯值

ipc_set 在程序有足夠許可權的前提下,把訊息佇列的當前關聯值設定為msqid_ds資料結構中給出的值

ipc_rmid 刪除訊息佇列

返回值: 

成功返回0,失敗返回-1

3.msgsnd

功能:把一條訊息新增到訊息佇列中 

原型:#include

#include

#include

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

引數: 

msgid:由msgget函式返回的訊息佇列標識碼 

msgp:指標指向準備傳送的訊息 

msgze:msgp指向的訊息的長度(不包括訊息型別的long int長整型) 

msg***:預設為0 

返回值:成功返回0,失敗返回-1

訊息結構一方面必須小於系統規定的上限,另一方面必須以乙個long int長整型開始,接受者以此來確定訊息的型別

struct msgbuf

;4.msgrcv

功能:是從乙個訊息佇列接受訊息 

原型: 

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

引數:與msgsnd相同 

返回值:成功返回實際放到接收緩衝區裡去的字元個數,失敗返回-1

此外,我們還需要學習兩個重要的命令 

前面我們說過,訊息佇列需要手動刪除ipc資源 

ipcs:顯示ipc資源 

ipcrm:手動刪除ipc資源 

下面用**模擬實現client與server之間的通訊 

comm.h

#ifndef _comm_h_

#define _comm_h_

#include

#include

#include

#include

#include

#include

struct msgbuf

;#define server_type 1

#define client_type 2

int createmsgqueue();

int getmsgqueue();

int destorymsgqueue(int msg_id);

int sendmsgqueue(int msg_id, int who, char* msg);

int recvmsgqueue(int msg_id, int recvtype, char out);

#endif

comm.c

#include "comm.h"

static int commmsgqueue(int flags)

int msg_id = msgget(key, flags);

if(msg_id < 0)

return msg_id;

}int createmsgqueue()

int getmsgqueue()

int destorymsgqueue(int msg_id)

return 0;

}int sendmsgqueue(int msg_id, int who, char* msg)

return 0;

}int recvmsgqueue(int msg_id, int recvtype, char out)

strncpy(out, buf.mtext, size);

out[size] = 0;

return 0;

}server.c

#include "comm.h"

int main()

;while(1)

}destorymsgqueue(msgid);

return 0;

}client.c

#include "comm.h"

int main()

;while(1)

recvmsgqueue(msgid, server_type, buf);

printf("server# %s\n", buf);

}return 0;

}

linux程序間通訊之訊息佇列

訊息佇列就是乙個訊息的鍊錶。可以把訊息看作乙個記錄,具有特定的格式以及特定的優先順序。對訊息佇列有寫許可權的程序可以向中按照一定的規則新增新訊息 對訊息佇列有讀許可權的程序則可以從訊息佇列中讀走訊息。include include include include include include in...

linux程序間通訊之訊息佇列

訊息佇列 使用訊息佇列的好處 可以給訊息附加特定的訊息型別。訊息佇列用於同一臺計算機的程序間的通訊。include include key t ftok const char pathname,int proj id 該函式根據檔名生成乙個id 系統建立ipc 通訊 訊息佇列 訊號量和共享記憶體 時...

Linux程序間通訊之訊息佇列

實現功能 編寫程式sender,它建立乙個訊息佇列 然後,迴圈等待使用者通過終端輸入一串字元,將這串字元通過訊息佇列傳送給receiver,直到使用者輸入 bye 為止 最後,它向receiver程序傳送訊息 end 並且等待receiver的應答,等到應答訊息後,將接收到的應答資訊顯示在終端螢幕上...