1. 程式人生 > >linux 訊息佇列使用

linux 訊息佇列使用

學習API當然用man嘍。

API:

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

int msgget(key_t key, int msgflg);
get a message queue identifier
key -- 關鍵字
msgflg -- 標誌 IPC_CREAT 或 IPC_EXCL
一般使用msgget建立訊息佇列,key自定義一個,如果系統已經使用了該key值,那有可能就建立失敗了。
還有建立完許可權的問題,這個還沒有深入研究。
return -- -1 if error and errno indicating the error.

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
傳送訊息
msgp -- 指向訊息的結構,例如訊息的結構如下
struct msgbuf {
  long mtype;       /* message type, must be > 0 */
  char mtext[64];    /* message data */
};
其中 mtest 陣列的大小就是 msgsz 的值。 
mtype -- 訊息型別,在接收時需要這個值用來區分各個訊息。注意,這個取值是有講究的。
The mtype field must have a strictly positive integer value. 正數可以,負數就不行!!!
msgflg -- 標誌 IPC_NOWAIT MSG_EXCEPT MSG_NOERROR 等,
return -- -1 if error and errno indicating the error.

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
接收訊息
知道傳送的話,接收就容易了。


int msgctl (int msqid, int cmd, struct msqid_ds *buf)
訊息佇列屬性控制
msqid:訊息佇列的識別符號。
cmd:執行的控制命令,即要執行的操作。(包括以下選項:
IPC_STAT:讀取訊息佇列屬性。取得此佇列的msqid_ds 結構,並將其存放在buf指向的結構中。
IPC_SET :設定訊息佇列屬性。
IPC_RMID:刪除訊息佇列。
IPC_INFO:讀取訊息佇列基本情況。此命令等同於 ipcs 命令。
這 4 條命令(IPC_STAT、IPC_SET、IPC_INFO 和 IPC_RMID)也可用於訊號量和共享儲存。)

buf:臨時的 msqid_ds 結構體型別的變數。用於儲存讀取的訊息佇列屬性或需要修改的訊息佇列屬性。

舉例:msgctl(qid, IPC_RMID, NULL) //刪除訊息佇列

看了API,就可以寫兩個程序跑一下了。

process1

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

#define MY_MSG_TYPE 0xaabb
struct msg {
    long msg_types;
    char msg_buf[3];
};

static key_t mykey = 0x1234;

static char buf[5][3] =
{
    { 'a', 'b', 'c'},
    { 'd', 'e', 'r'},
    { 'g', 'h', 'i'},
    { 'j', 'k', 'l'},
    { 'm', 'n', 'o'}
};

int main()
{
    struct msg pmsg;
    int msgid;
    int i;
    int ret;

    printf("process send start\n");
    i = 0;
    msgid = msgget(mykey, IPC_CREAT | 00666);
    if (msgid < 0) {
        printf("creat msg failed\n");
        return 0;
    }

    pmsg.msg_types = MY_MSG_TYPE;

    while (1) {
        memcpy(&pmsg.msg_buf, &(buf[i][0]), 3);

        printf("msgid %d pmsg.msg_buf %c %c %c\n", msgid, pmsg.msg_buf[0], pmsg.msg_buf[1], pmsg.msg_buf[2]);
        ret = msgsnd(msgid, &pmsg, 3, IPC_NOWAIT);
        if (ret < 0) {
            switch (errno)
			{
				case E2BIG:	printf("<xmpp>1111訊息文字長度大於msgsz,並且msgflg中沒有指定MSG_NOERROR\n");	break;
				case EACCES: printf("<xmpp>2222呼叫程序沒有讀權能,同時沒具有CAP_IPC_OWNER權能\n"); break;
				case EAGAIN: printf("<xmpp>3333訊息佇列為空,並且msgflg中沒有指定IPC_NOWAIT\n"); break;
				case EFAULT: printf("<xmpp>444msgp指向的空間不可訪問\n"); break;
				case EIDRM: printf("<xmpp>555當程序睡眠等待接收訊息時,訊息佇列已被刪除\n"); break;
				case EINTR: printf("<xmpp>666當程序睡眠等待接收訊息時,被訊號中斷\n"); break;
				case EINVAL: printf("<xmpp>777 inval\n"); break;
				case ENOMSG: printf("<xmpp>888msgflg中指定了IPC_NOWAIT,同時所請求型別的訊息不存在\n"); break;
				default: printf("<xmpp>999其他錯誤\n"); break;
			}
            break;
        }
        i++;
        if (i >= 5) {
            i = 0;
        }

        sleep(3);
    }

    msgctl(msgid, IPC_RMID, NULL);

    return 0;
}

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

#define MY_MSG_TYPE 0xaabbccdd

struct msg {
    long msg_types;
    char msg_buf[3];
};

static key_t mykey = 0x1234;

int main()
{
    struct msg pmsg;
    int msgid;
    int i;
    ssize_t ret;

    printf("process receive start\n");

    printf("aaaaaaaaaaaaaaaaaa\n");

    i = 0;
    msgid = msgget(mykey, IPC_CREAT | 00666);
    if (msgid < 0) {
        printf("GET MSG FAILE\n");
        return 0;
    }
    printf("!!!!\n");
    while (1) {
        ret = msgrcv(msgid, &pmsg, 3, MY_MSG_TYPE, 0);
        if (ret < 0) {
            printf("receive error!!!\n");

        } else {
            printf("get message ret = %d %c %c %c\n", ret, pmsg.msg_buf[0], pmsg.msg_buf[1], pmsg.msg_buf[2]);
        }

        sleep(1);
    }

    msgctl(msgid, IPC_RMID, NULL);

    return 0;
}

把 process2 放在後臺執行,再執行 process1。

就會有列印了

.out  main.c
[[email protected] p1]$ ./a.out 
process send start
msgid 884736 pmsg.msg_buf a b c
get message ret = 3 a b c

成功。

相關推薦

C++封裝Linux訊息佇列

訊息佇列是Linux程序間通訊方式之一,在面向物件程式設計中,需要對其封裝。 一、訊息佇列的特點 1、非同步通訊,訊息佇列會儲存程序傳送的訊息,其他程序不一定要及時取走訊息。 2、可以傳送不同型別的訊息,訊息的頭部用long型別的欄位標記。 3、取訊息時,不一定按先進

Linux訊息佇列與執行緒例項理解

相較於程序,執行緒不僅擁有程序的併發性,相互獨立等特點,更有佔用資源較少,效率高等特點。 建立執行緒 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)

Linux訊息佇列實現程序間通訊

什麼是訊息佇列: 訊息佇列提供了從一個程序向另一個程序傳送一個有型別資料塊的方法。用這種方法可以避免命名管道的同步和阻塞問題。訊息佇列是基於訊息的,而管道是基於位元組流的,並且訊息佇列的讀取不一定是先入先出。 訊息佇列的操作: 訊息佇列的建立或者獲取: int msgg

linux 訊息佇列使用

學習API當然用man嘍。 API: #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgget(key_t key, int msgflg);

linux訊息佇列的核心限制

訊息佇列: 1.每次msgrcv一個訊息,1.那個訊息會在核心中移除 2.每次msgrcv都只會給一個訊息出來,不管你rcv用多大的buf來接收,都是可以的。如果msgrcv的bufSize小於實際的該訊息的大小,那麼可以設定一個標誌:表示截斷。 如果不設定,那麼會報錯

Linux訊息佇列詳解

Linux的訊息佇列(queue)實質上是一個連結串列, 它有訊息佇列識別符號(queue ID). msgget建立一個新佇列或開啟一個存在的佇列; msgsnd向佇列末端新增一條新訊息; msgrcv從佇列中取訊息, 取訊息是不一定遵循先進先出的, 也可以按訊息的型別欄位取訊息.  1. 識別符號(des

Linux-程序通訊-訊息佇列/訊號燈/共享記憶體

訊息佇列     訊息佇列提供了程序間傳送資料塊的方法,每個資料塊都可以被認為是有一個型別,接受者接受的資料塊可以有不同的型別;我們可以通過傳送訊息來避免命名管道的同步和阻塞問題;訊息佇列與命名管道一樣,每個資料塊都有一個最大長度的限制;我們可以將每個資料塊當作是一

Linux:程序間通訊(匿名管道命名管道)(共享記憶體,訊息佇列,訊號量)

目錄 程序間通訊的介紹 管道 匿名管道 原理: 程式碼實現 匿名管道特性 實現管道符 |  命名管道 命名管道特性 程式碼實現 管道讀寫規則 作業系統中ipc的相關命令 共享記憶體(重點) 生命週期: 程式碼實現 程式碼實現獲

linux c程式設計:Posix訊息佇列

 Posix訊息佇列可以認為是一個訊息連結串列. 有足夠寫許可權的執行緒可以往佇列中放置訊息, 有足夠讀許可權的執行緒可以從佇列中取走訊息 在某個程序往一個佇列寫入訊息前, 並不需要另外某個程序在該佇列上等待訊息的到達. 這跟管道和FIFO是相反的, 因為

Linux 核心 IPC 通訊原始碼分析-訊息佇列

簡介 目的 本文對最新的 Linux-4.19.4 核心原始碼進行分析,並詳細指出核心 IPC 機制中的訊息佇列的原理。 程序間通訊 IPC(程序間通訊,InterProcess Communication)是核心提供的系統中程序間進行通訊的一種機制。系統中每個程序的使用者地

Linux程序通訊——訊息佇列

總結下別人比較好的博文+自己寫的一個栗子   1.ftok()    https://blog.csdn.net/u013485792/article/details/50764224      &

Linux關於程序間通訊訊息佇列

訊息佇列概念 訊息佇列提供了一個從一個程序向另外一個程序傳送一塊資料的方法 每個資料塊都被認為是有一個型別,接收者程序接收的資料塊可以有不同的型別值 訊息佇列也有管道一樣的不足,就是每個資料塊的最大長度是有上限的,系統上全體佇列的最大總長度也有一個上限 訊息佇列函式操作

Linux中程序間通訊機制----訊息佇列

一、什麼是訊息 訊息(message)是一個格式化的可變長的資訊單元。訊息機制允許由一個程序給其它任意的程序傳送一個訊息。當一個程序收到多個訊息時,可將它們排成一個訊息佇列。 1、訊息機制的資料結構 (1)訊息首部 記錄一些與訊息有關的資訊,如訊息的型別、大小、

嵌入式Linux併發程式設計,程序間通訊方式,System V IPC,訊息佇列,開啟/建立msgget(), 傳送訊息msgsnd(),格式,接收訊息msgrcv(),控制訊息佇列 msgctl()

文章目錄 1,訊息佇列 2,訊息佇列結構 3,訊息佇列使用步驟 3.1,開啟/建立訊息佇列 msgget() 3.1.1,開啟/建立訊息佇列---示例msgget() 3.2,向訊息佇列傳送訊息 msgs

Linux系統程式設計——程序間通訊:訊息佇列

概述 訊息佇列提供了一種在兩個不相關的程序之間傳遞資料的簡單高效的方法,其特點如下: 1)訊息佇列可以實現訊息的隨機查詢。訊息不一定要以先進先出的次序讀取,程式設計時可以按訊息的型別讀取。 2)訊息佇列允許一個或多個程序向它寫入或者讀取訊息。 3)與無名管道、命名管道一

LinuxLinux程序間通訊之訊息佇列

1、訊息佇列概念引入    訊息佇列提供了一個從一個程序向另外一個程序傳送一塊資料的方法每個資料塊都被認為是有一個型別,接收者程序接收的資料塊可以有不同的型別值訊息佇列也有管道一樣的不足,就是每個訊息的最大長度是有上限的(MSG

Linux 學習筆記—程序通訊之 訊息佇列、訊號量、共享記憶體的概念區別聯絡

2.5 訊息佇列(Message queues) 訊息佇列是核心地址空間中的內部連結串列,通過linux核心在各個程序直接傳遞內容,訊息順序地傳送到訊息佇列中,並以幾種不同的方式從佇列中獲得,每個訊息佇列可以用IPC識別符號唯一地進行識別。核心中的訊息佇列是通過

Linux作業系統--訊息佇列

     1、訊息佇列的特點    (1)訊息佇列是訊息的連結串列,具有特定的格式,存放在記憶體中並由訊息佇列識別符號標識.     (2)訊息佇列允許一個或多個程序向它寫入與讀取訊息.     (3)管道和命名管道都是通訊資料都是先進先出的原則。     (4)訊息佇列可以實現訊息的隨機查詢,訊息不一定要

Linux環境程序間通訊(三) 訊息佇列(轉)

轉自http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/, 作者:鄭彥興訊息佇列(也叫做報文佇列)能夠克服早期unix通訊機制的一些缺點。作為早期unix通訊機制之一的訊號能夠傳送的資訊量有限,後來雖然 POSIX 1003.1b在訊號的實時性方面作了

linux開發】程序間通訊命名管道-共享記憶體-記憶體對映-訊息佇列-訊號量

程序間通訊命名管道-共享記憶體-記憶體對映-訊息佇列-訊號量  在Unix平臺上,建立命名管道是建立了一個fifo檔案,和在shell下面用mkfifo命令的效果是一樣的。看起來這個管道檔案就是一個普通的檔案系統瓜掛載點,但是它只不過是作為一個名稱存在,實際的內容是一塊系統