1. 程式人生 > >Linux系統下-程序間通訊(訊息佇列-詳解)

Linux系統下-程序間通訊(訊息佇列-詳解)

Linux下程序間通訊方式:

# 管道( pipe ):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。

# 有名管道 (named pipe) : 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。

# 訊號量( semophore ) : 訊號量是一個計數器,可以用來控制多個程序對共享資源的訪問。它常作為一種鎖機制,防止某程序正在訪問共享資源時,其他程序也訪問該資源。因此,主要作為程序間以及同一程序內不同執行緒之間的同步手段。

# 訊息佇列( message queue ) : 訊息佇列是由訊息的連結串列,存放在核心中並由訊息佇列識別符號標識。訊息佇列克服了訊號傳遞資訊少、管道只能承載無格式位元組流以及緩衝區大小受限等缺點。

# 訊號 ( sinal ) : 訊號是一種比較複雜的通訊方式,用於通知接收程序某個事件已經發生。

# 共享記憶體( shared memory ) :共享記憶體就是對映一段能被其他程序所訪問的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以訪問。共享記憶體是最快的 IPC 方式,它是針對其他程序間通訊方式執行效率低而專門設計的。它往往與其他通訊機制,如訊號兩,配合使用,來實現程序間的同步和通訊。

# 套接字( socket ) : 套解口也是一種程序間通訊機制,與其他通訊機制不同的是,它可用於不同及其間的程序通訊。

System V 與 POSIX的區別:
System V IPC
存在時間比較老,許多系統都支援,但是介面複雜,並且可能各平臺上實現略有區別(如ftok的實現及限制)。
POSIX是新標準,現在多數UNIX也已實現,我覺得如果只是開發的話,那麼還是POSIX好,因為語法簡單,並且各平臺上實現都一樣。

一、什麼是訊息佇列 訊息佇列提供了一種從一個程序向另一個程序傳送一個數據塊的方法。  每個資料塊都被認為含有一個型別,接收程序可以獨立地接收含有不同型別的資料結構。我們可以通過傳送訊息來避免命名管道的同步和阻塞問題。但是訊息佇列與命名管道一樣,每個資料塊都有一個最大長度的限制。 Linux用巨集MSGMAX和MSGMNB來限制一條訊息的最大長度和一個佇列的最大長度。 1、每種程序通訊方式實現方式和功能不一樣,帶來適用的場景也有所不同:
訊息佇列是連結串列佇列,它通過核心提供一個struct msqid_ds *msgque[MSGMNI]向量維護核心的一個訊息佇列列表,因此linux系統支援的最大訊息佇列數由msgque陣列大小來決定,每一個msqid_ds表示一個訊息佇列,並通過msqid_ds.msg_first、msg_last維護一個先進先出的msg連結串列佇列,當傳送一個訊息到該訊息佇列時,把傳送的訊息構造成一個msg結構物件,並新增到msqid_ds.msg_first、msg_last維護的連結串列佇列,同樣,接收訊息的時候也是從msg連結串列佇列尾部查詢到一個msg_type匹配的msg節點,從連結串列佇列中刪除該msg節點,並修改msqid_ds結構物件的資料。

2、訊息佇列的資料結構

struct msqid_ds *msgque[MSGMNI]向量:

       msgque[MSGMNI]是一個msqid_ds結構的指標陣列,每個msqid_ds結構指標代表一個系統訊息佇列,msgque[MSGMNI]的大小為MSGMNI=128,也就是說系統最多有MSGMNI=128個訊息佇列。

3、訊息佇列Key的獲取

        在程式中若要使用訊息佇列,必須要能知道訊息佇列key,因為應用程序無法直接訪問核心訊息佇列中的資料結構,因此需要一個訊息佇列的標識,讓應用程序知道當前操作的是哪個訊息佇列,同時也要保證每個訊息佇列key值的唯一性

http://blog.csdn.net/stonecao/article/details/10364287

二、訊息佇列與命名管道的比較 訊息佇列跟命名管道有不少的相同之處,通過與命名管道一樣,訊息佇列進行通訊的程序可以是不相關的程序,同時它們都是通過傳送和接收的方式來傳遞資料的。在命名管道中,傳送資料用write,接收資料用read,則在訊息佇列中,傳送資料用msgsnd,接收資料用msgrcv。而且它們對每個資料都有一個最大長度的限制。 與命名管道相比,訊息佇列的優勢在於,1、訊息佇列也可以獨立於傳送和接收程序而存在,從而消除了在同步命名管道的開啟和關閉時可能產生的困難。2、同時通過傳送訊息還可以避免命名管道的同步和阻塞問題,不需要由程序自己來提供同步方法。3、接收程式可以通過訊息型別有選擇地接收資料,而不是像命名管道中那樣,只能預設地接收。
1、建立或者使用訊息佇列:msgget函式 該函式用來建立和訪問一個訊息佇列。它的原型為:
int msgget(key_t, key, int msgflg);

與其他的IPC機制一樣,程式必須提供一個鍵來命名某個特定的訊息佇列。msgflg是一個許可權標誌,表示訊息佇列的訪問許可權,它與檔案的訪問許可權一樣。msgflg可以與IPC_CREAT做或操作,表示當key所命名的訊息佇列不存在時建立一個訊息佇列,如果key所命名的訊息佇列存在時,IPC_CREAT標誌會被忽略,而只返回一個識別符號。

在程式中若要使用訊息佇列,必須要能知道訊息佇列key,因為應用程序無法直接訪問核心訊息佇列中的資料結構,因此需要一個訊息佇列的標識,讓應用程序知道當前操作的是哪個訊息佇列,同時也要保證每個訊息佇列key值的唯一性。

申請一塊記憶體,建立一個新的訊息佇列(資料結構msqid_ds),將其初始化後加入到msgque向量表中的某個空位置處,返回標示符。或者在msgque向量表中找鍵值為key的訊息佇列。

2、將訊息新增到訊息佇列中:

int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);

msgid是由msgget函式返回的訊息佇列識別符號。

msg_ptr是一個指向準備傳送訊息的指標,但是訊息的資料結構卻有一定的要求,指標msg_ptr所指向的訊息結構一定要是以一個長整型成員變數開始的結構體,接收函式將用這個成員來確定訊息的型別。所以訊息結構要定義成這樣:
struct my_message{  
    long int message_type;  
    /* The data you wish to transfer*/  
};
msg_sz是msg_ptr指向的訊息的長度,注意是訊息的長度,而不是整個結構體的長度,也就是說msg_sz是不包括長整型訊息型別成員變數的長度。 msgflg用於控制當前訊息佇列滿或佇列訊息到達系統範圍的限制時將要發生的事情。 如果呼叫成功,訊息資料的一分副本將被放到訊息佇列中,並返回0,失敗時返回-1. 3、從一個訊息佇列中獲取訊息:
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
msgid, msg_ptr, msg_st的作用也函式msgsnd函式的一樣。 msgtype可以實現一種簡單的接收優先順序。如果msgtype為0,就獲取佇列中的第一個訊息。如果它的值大於零,將獲取具有相同訊息型別的第一個資訊。如果它小於零,就獲取型別等於或小於msgtype的絕對值的第一個訊息。 msgflg用於控制當佇列中沒有相應型別的訊息可以接收時將發生的事情。 呼叫成功時,該函式返回放到接收快取區中的位元組數,訊息被複制到由msg_ptr指向的使用者分配的快取區中,然後刪除訊息佇列中的對應訊息。失敗時返回-1.
4、訊息佇列控制函式:
int msgctl(int msgid, int command, struct msgid_ds *buf);
command是將要採取的動作,它可以取3個值,     IPC_STAT:把msgid_ds結構中的資料設定為訊息佇列的當前關聯值,即用訊息佇列的當前關聯值覆蓋msgid_ds的值。     IPC_SET:如果程序有足夠的許可權,就把訊息列隊的當前關聯值設定為msgid_ds結構中給出的值
    IPC_RMID:刪除訊息佇列 buf是指向msgid_ds結構的指標,它指向訊息佇列模式和訪問許可權的結構。msgid_ds結構至少包括以下成員:
struct msgid_ds  
{  
    uid_t shm_perm.uid;  
    uid_t shm_perm.gid;  
    mode_t shm_perm.mode;  
};
成功時返回0,失敗時返回-1. 訊息傳送端:send.c
/*send.c*/  
#include <stdio.h>   
#include <sys/types.h>   
#include <sys/ipc.h>   
#include <sys/msg.h>   
#include <errno.h>   

#define MSGKEY 1024   
  
struct msgstru  
{  
   long msgtype;  
   char msgtext[2048];   
};  
  
main()  
{  
  struct msgstru msgs;  
  int msg_type;  
  char str[256];  
  int ret_value;  
  int msqid;  
  
  msqid=msgget(MSGKEY,IPC_EXCL);  /*檢查訊息佇列是否存在*/  
  if(msqid < 0){  
    msqid = msgget(MSGKEY,IPC_CREAT|0666);/*建立訊息佇列*/  
    if(msqid <0){  
    printf("failed to create msq | errno=%d [%s]\n",errno,strerror(errno));  
    exit(-1);  
    }  
  }   
   
  while (1){  
    printf("input message type(end:0):");  
    scanf("%d",&msg_type);  
    if (msg_type == 0)  
       break;  
    printf("input message to be sent:");  
    scanf ("%s",str);  
    msgs.msgtype = msg_type;  
    strcpy(msgs.msgtext, str);  
    /* 傳送訊息佇列 */  
    ret_value = msgsnd(msqid,&msgs,sizeof(struct msgstru),IPC_NOWAIT);  
    if ( ret_value < 0 ) {  
       printf("msgsnd() write msg failed,errno=%d[%s]\n",errno,strerror(errno));  
       exit(-1);  
    }  
  }  
  msgctl(msqid,IPC_RMID,0); //刪除訊息佇列   
}

訊息接收端 receive.c
/*receive.c */  
#include <stdio.h>   
#include <sys/types.h>   
#include <sys/ipc.h>   
#include <sys/msg.h>   
#include <errno.h>   
  
#define MSGKEY 1024   
  
struct msgstru  
{  
   long msgtype;  
   char msgtext[2048];  
};  
  
/*子程序,監聽訊息佇列*/  
void childproc(){  
  struct msgstru msgs;  
  int msgid,ret_value;  
  char str[512];  
    
  while(1){  
     msgid = msgget(MSGKEY,IPC_EXCL );/*檢查訊息佇列是否存在 */  
     if(msgid < 0){  
        printf("msq not existed! errno=%d [%s]\n",errno,strerror(errno));  
        sleep(2);  
        continue;  
     }  
     /*接收訊息佇列*/  
     ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),0,0);  
     printf("text=[%s] pid=[%d]\n",msgs.msgtext,getpid());  
  }  
  return;  
}  
  
void main()  
{  
  int i,cpid;  
  
  /* create 5 child process */  
  for (i=0;i<5;i++){  
     cpid = fork();  
     if (cpid < 0)  
        printf("fork failed\n");  
     else if (cpid ==0) /*child process*/  
        childproc();  
  }  
}

若父程序退出,子程序尚未結束,則子程序會被init程序領養,也就是說init程序將成為該子程序的父程序。

若希望父程序退出,子程序也退出的話,可以使用執行緒,因為若程序結束,則還沒結束的執行緒一定會立刻結束。

另外:以上是system v標準下的訊息佇列介面,如果要使用POSIX標準來建立訊息佇列1、mq_open來建立非默認個數大小訊息佇列:

函式原型

mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
 第4個引數為 mq_attr 指標
 struct mq_attr{ 
   long mq_flags;
   
   long mq_maxmsg;
   
   long mq_msgsize;
   
   long mq_curmsgs;
};
 當第四個引數為空指標時,就使用預設屬性。  
當指向mq_attr結構的指標作為引數時,允許我們在該函式的實際操作時建立一個新佇列時,給它指定mq_maxmsg和mq_msgsize屬性.mq_open忽略該結構的另外兩個成員.

(1)attr.mq_maxmsg 不能超過檔案 /proc/sys/fs/mqueue/msg_max 中的數值;

(2)attr.mq_msgsize不能超過 /proc/sys/fs/mqueue/msgsize_max 的數值;

(3)訊息佇列名稱前面必須加上斜杆。

在POSIX訊息佇列中 msg_max 預設為 10 ,msgsize_max 預設為8192 ,否則會報錯!!!
可以在 /proc/sys/fs/mqueue# cat msg_max 
  /proc/sys/fs/mqueue# cat msgsize_max
檢視
修改的話,要使用:echo 1000 > /proc/sys/fs/mqueue/msg_max往裡面寫。

2、獲取訊息佇列的屬性 
一個程序在傳送和接收訊息之前,需要了解訊息物件的屬性,如訊息的最大長度。以便
設定接收和傳送的buffer大小。 mqd_t mq_getattr(mqd_t mqdes, struct mq_attr *attr);引數: 
Mqdes:開啟訊息佇列時獲取的描述符。 
Attr:指向結構struct mq_attr的指標,用來獲取訊息佇列的四個屬性 
struct mq_attr { 
    long mq_flags;    // 0或者O_NONBLOCK 
    long mq_maxmsg; //佇列中包含的訊息數的最大限制數  

    long mq_msgsize; //每個訊息大小的最大限制數

    long mq_curmsgs;  //當前佇列中的訊息數 


  
3、設定訊息佇列屬性 
我們可以設定訊息佇列的屬性,實際只能設定flag標誌,說明佇列中沒有訊息時,接收訊息的程序是否在佇列上繼續等待。 
mqd_t mq_setattr(mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr); 
引數: 
Mqdes:開啟訊息佇列時獲取的描述符。 
Attr:指向結構struct mq_attr的指標,用來獲取訊息佇列的最大訊息個數和最大訊息長
度。放到資料結構的mq_maxmsg和mq_msgsize中。

 struct mq_attr { 
    long mq_flags;    // 0或者O_NONBLOCK,只能設定這個

    long mq_maxmsg; //佇列中包含的訊息數的最大限制數 

    long mq_msgsize; //每個訊息大小的最大限制數   

    long mq_curmsgs;  //當前佇列中的訊息數

 } 
oldattr:用來儲存設定之前的attr值,可以為NULL. 

4、傳送訊息 
程序在開啟訊息佇列後,可以使用下面的函式傳送訊息 
int mq_send(mqd_t mqdes, const char *ptr, size_t len, unsigned int prio); 
引數: 
mqdes: 開啟訊息佇列時獲得的描述符。 
ptr: 指向傳送緩衝區的指標,傳送緩衝區存放了要傳送的資料。 
Len: 要傳送的資料的長度。 prio :訊息的優先順序;它是一個小於 MQ_PRIO_MAX 的數,數值越大,優先順序越高。 
POSIX 訊息佇列在呼叫 mq_receive 時總是返回佇列中 最高優先順序的最早訊息 。如果訊息不需要設定優先順序,那麼可以在 mq_send 是置 prio 為 0 , mq_receive 的 prio 置為 NULL 。  返回值:傳送成功,返回0,失敗,返回-1.    


5、接收訊息 
程序在開啟訊息佇列後,可以使用下面的函式接收訊息。 
ssize_t mq_receive(mqd_t mqdes, char *ptr, size_t len, unsigned int *prio); 
引數: 
mqdes: 開啟訊息佇列時獲得的描述符。 
ptr: 指向接收緩衝區的指標。接收緩衝區用來存放收到的訊息。 
Len: 接收緩衝區的長度。 len不能小於mq_msgsize,否則會返回EMSGSIZE prio :訊息的優先順序;它是一個小於 MQ_PRIO_MAX 的數,數值越大,優先順序越高。 POSIX 訊息佇列在呼叫 mq_receive 時總是返回佇列中 最高優先順序的最早訊息 。如果訊息不需要設定優先順序,那麼可以在 mq_send 是置 prio 為 0 , mq_receive 的 prio 置為 NULL 。 返回值:  接收成功,返回0,失敗,返回-1.

6、訊息佇列的關閉 
mqd_t mq_close(mqd_t mqdes); 關閉訊息佇列,但不能刪除它 成功返回0,失敗返回-1   

7、刪除訊息佇列 
 mqd_t mq_unlink(const char *name); 成功返回0,失敗返回-1 
當某個程序還沒有關閉此訊息佇列時,呼叫mq_unlink時,不會馬上刪除佇列,當最後一個程序關閉佇列時,該佇列被刪除

編譯:

gcc -o consumer consumer.c -lrt

gcc -o producer producer.c -lrt

/*

 *
 *       Filename:  producer.c
 *
 *    Description:  生產者程序
 *
 *        Version:  1.0
 *        Created:  09/30/2011 04:52:23 PM
 *       Revision:  none
 *       Compiler:  gcc(g++)
 *
 *         Author:  |Zhenghe Zhang|, |[email protected]|
 *        Company:  |Shenzhen XXX Technology Co., Ltd.|
 *
 */

#include <stdio.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

#define MAXSIZE     10   //定義buf大小
#define BUFFER      8192 //定義Msg大小

struct MsgType{
    int len;
    char buf[MAXSIZE];
    char x;
    short y;
};

int main() 
{ 
    /*訊息佇列*/
    mqd_t msgq_id;
    struct MsgType msg;

    unsigned int prio = 1;
    unsigned int send_size = BUFFER;

    struct mq_attr msgq_attr;
    const char *file = "/posix";

    /*mq_open() for creating a new queue (using default attributes) */
    /*mq_open() 建立一個新的 POSIX 訊息佇列或開啟一個存在的佇列*/
    msgq_id = mq_open(file, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG, NULL);
    if(msgq_id == (mqd_t)-1)
    {
        perror("mq_open");
        exit(1);
    }

    /* getting the attributes from the queue        --  mq_getattr() */
    if(mq_getattr(msgq_id, &msgq_attr) == -1)
    {
        perror("mq_getattr");
        exit(1);
    }

    printf("Queue \"%s\":\n\t- stores at most %ld messages\n\t- \
        large at most %ld bytes each\n\t- currently holds %ld messages\n", 
        file, msgq_attr.mq_maxmsg, msgq_attr.mq_msgsize, msgq_attr.mq_curmsgs);
   
    /*setting the attributes of the queue        --  mq_setattr() */
    /*mq_setattr() 設定訊息佇列的屬性,設定時使用由 newattr 指標指向的 mq_attr 結構的資訊。*/
    /*屬性中只有標誌 mq_flasgs 裡的 O_NONBLOCK 標誌可以更改,其它在 newattr 內的域都被忽略 */
    if(mq_setattr(msgq_id, &msgq_attr, NULL) == -1)
    {
        perror("mq_setattr");
        exit(1);
    }   

    int i = 0; 
    while(i < 10) 
    {
        msg.len = i;
        memset(msg.buf, 0, MAXSIZE);
        sprintf(msg.buf, "0x%x", i);
        msg.x = (char)(i + 'a');
        msg.y = (short)(i + 100);

        printf("msg.len = %d, msg.buf = %s, msg.x = %c, msg.y = %d\n", msg.len, msg.buf, msg.x, msg.y);

        /*sending the message      --  mq_send() */
        /*mq_send() 把 msg_ptr 指向的訊息加入由 mqdes 引用的訊息佇列裡。*/
        /*引數 msg_len 指定訊息 msg_ptr 的長度:這個長度必須小於或等於佇列 mq_msgsize 屬性的值。零長度的訊息是允許。*/
        if(mq_send(msgq_id, (char*)&msg, sizeof(struct MsgType), prio) == -1)
        {
            perror("mq_send");
            exit(1);
        }

        i++;
        sleep(1);   
    }

    sleep(30); //等待消費者程序退出

    /*closing the queue        -- mq_close() */
    /*mq_close() 關閉訊息佇列描述符 mqdes。如果呼叫程序在訊息佇列 mqdes 綁定了通知請求,*/
    /*那麼這個請求被刪除,此後其它程序就可以繫結通知請求到此訊息佇列。*/
    if(mq_close(msgq_id) == -1)
    {
        perror("mq_close");
        exit(1);
    }

    /*mq_unlink() 刪除名為 name 的訊息佇列。訊息佇列名將被直接刪除。*/
    /*訊息佇列本身在所有引用這個佇列的描述符被關閉時銷燬。*/
    if(mq_unlink(file) == -1)
    {
        perror("mq_unlink");
        exit(1);
    }

    return 0; 
}

 


/*
 *
 *       Filename:  consumer.c
 *
 *    Description:  消費者程序
 *
 *        Version:  1.0
 *        Created:  09/30/2011 04:52:23 PM
 *       Revision:  none
 *       Compiler:  gcc(g++)
 *
 *         Author:  |Zhenghe Zhang|, |[email protected]|
 *        Company:  |Shenzhen XXX Technology Co., Ltd.|
 *
 */

#include <stdio.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

#define MAXSIZE     10   //定義buf大小
#define BUFFER      8192 //定義Msg大小

struct MsgType{
    int len;
    char buf[MAXSIZE];
    char x;
    short y;
};

int main() 
{ 
    /*訊息佇列*/
    mqd_t msgq_id;
    struct MsgType msg;

    unsigned int sender;
    struct mq_attr msgq_attr;

    unsigned int recv_size = BUFFER;
    const char *file = "/posix";

    /* mq_open() for opening an existing queue */
    msgq_id = mq_open(file, O_RDWR);
    if(msgq_id == (mqd_t)-1)
    {
        perror("mq_open");
        exit(1);
    }

    /* getting the attributes from the queue        --  mq_getattr() */
    if(mq_getattr(msgq_id, &msgq_attr) == -1)
    {
        perror("mq_getattr");
        exit(1);
    }

    printf("Queue \"%s\":\n\t- stores at most %ld messages\n\t- \
        large at most %ld bytes each\n\t- currently holds %ld messages\n", 
        file, msgq_attr.mq_maxmsg, msgq_attr.mq_msgsize, msgq_attr.mq_curmsgs);

    if(recv_size < msgq_attr.mq_msgsize)
        recv_size = msgq_attr.mq_msgsize;

    int i = 0;
    while(i < 10) //執行一個consumenr,為 10 ,同時執行兩個consumer程序,為 5  
    {
        msg.len = -1;
        memset(msg.buf, 0, MAXSIZE);
        msg.x = ' ';
        msg.y = -1;
 
        /* getting a message */

        /*mq_receive() 從由描述符 mqdes 引用的佇列時刪除優先順序最高的最老的訊息,並把放置到 msg_ptr 的快取區內。*/
        /*引數 msg_len 指定緩衝區 msg_ptr 的大小:它必須大於佇列的 mq_msgsize 屬性(引數 mq_getattr)。*/ 
        /*如果 prio 不是 NULL,那麼它指向的記憶體用於返回收到訊息相關的優先順序。*/
        if (mq_receive(msgq_id, (char*)&msg, recv_size, &sender) == -1) 
        {
            perror("mq_receive");
            exit(1);
        }

        printf("msg.len = %d, msg.buf = %s, msg.x = %c, msg.y = %d\n", msg.len, msg.buf, msg.x, msg.y);

        i++;
        sleep(2); 
    }

    if(mq_close(msgq_id) == -1)
    {
        perror("mq_close");
        exit(1);
    }

    return 0; 
}


1、殭屍程序;2、共享記憶體;3、延時函式;4、kill訊號;5、fork子程序;6訊號量;

相關推薦

Linux系統-程序通訊訊息佇列-

Linux下程序間通訊方式: # 管道( pipe ):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。 # 有名管道 (named pipe) : 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序

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

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

Linux程序程式設計-之二-程序通訊訊息佇列

1.1         系統V訊息佇列 訊息佇列中的每個訊息都有如下的資料結構: struct msgbuf { long mtype;         // 訊息型別 char mtext[n];      // 訊息內容,n由使用者自己定義 }; 1.1.1      

IPC程序通訊訊息佇列

基本概念訊息佇列提供了一個從一個程序向另外一個程序傳送一塊資料的方法。每個資料塊都被認為是有一個型別,接收者程序接收的資料塊可以有不同的型別值。訊息佇列與管道同樣有缺陷,就是每個訊息的最大長度是有上限的(MSGMAX),每個訊息佇列的總的位元組數是有上限的(MSGMNB),系

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

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

Linux系統程式設計——程序通訊:管道pipe

管道的概述 管道也叫無名管道,它是是 UNIX 系統 IPC(程序間通訊) 的最古老形式,所有的 UNIX 系統都支援這種通訊機制。 無名管道有如下特點: 1、半雙工,資料在同一時刻只能在一個方向上流動。 2、資料只能從管道的一端寫入,從另一端讀出。

Linux-程序通訊訊息對列)

今天來介紹IPC通訊的第一種方式:訊息對列 由於程序具有獨立性,要想兩個程序之間有資料的往來,就必須讓兩個不相干的程序看到同一塊資源。前面有講到管道,也是一種公共資源。現在,我們介紹一種另一種公共資源:訊息對列 訊息對列,顧名思義,想必看到的公共資源可能就是

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

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

Linux系統程式設計——程序通訊:共享記憶體

概述 共享記憶體是程序間通訊中最簡單的方式之一。共享記憶體允許兩個或更多程序訪問同一塊記憶體,就如同 malloc() 函式向不同程序返回了指向同一個實體記憶體區域的指標。當一個程序改變了這塊地址中的內容的時候,其它程序都會察覺到這個更改。 共享記憶體的特點: 1)共

Linux系統程式設計——程序通訊:訊號中斷處理

什麼是訊號? 訊號是 Linux 程序間通訊的最古老的方式。訊號是軟體中斷,它是在軟體層次上對中斷機制的一種模擬,是一種非同步通訊的方式 。訊號可以導致一個正在執行的程序被另一個正在執行的非同步程序中斷,轉而處理某一個突發事件。 “中斷”在我們生活中經常遇到,譬如,我正在

Linux系統程式設計——程序通訊概述

程序是一個獨立的資源分配單元,不同程序(這裡所說的程序通常指的是使用者程序)之間的資源是獨立的,沒有關聯,不能在一個程序中直接訪問另一個程序的資源(例如開啟的檔案描述符)。 但是,程序不是孤立的,不同的程序需要進行資訊的互動和狀態的傳遞等,因此需要程序間通訊( IPC:Inter Pr

程序通訊方式-----訊息佇列

訊息佇列 訊息佇列,是訊息的連結表,存放在核心中。一個訊息佇列由一個識別符號(即佇列ID)來標識。使用者程序可以向訊息佇列新增訊息,也可以向訊息佇列讀取訊息。 同管道檔案相比,訊息佇列中的每個訊息指定特定的訊息型別,接收的時候可以不需要按照佇列次序讀取,可以根據自定義型別

LinuxLinux程序通訊訊息佇列

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

Linux 多工程式設計——程序通訊訊息佇列(Message Queues)

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

Linux程序通訊訊息佇列、訊號量和共享儲存

訊息佇列、訊號量和共享儲存是IPC(程序間通訊)的三種形式,它們功能不同,但有相似之處,下面先介紹它們的相似點,然後再逐一說明。 1、相似點 每個核心中的IPC結構(訊息佇列、訊號量和共享儲存)都用一個非負整數的識別符號加以引用,與檔案描述符不同,當一個

Linux程序通訊——使用訊息佇列

下面來說說如何用不用訊息佇列來進行程序間的通訊,訊息佇列與命名管道有很多相似之處。有關命名管道的更多內容可以參閱我的另一篇文章:Linux程序間通訊——使用命名管道 一、什麼是訊息佇列 訊息佇列提供了一種從一個程序向另一個程序傳送一個數據塊的方法。  每個資料塊都被認為含

linux 程序通訊訊息佇列以及例項

程式碼來自:嵌入式linux應用開發標準教程 訊息可以理解為寫信給某個人,這裡在應用中是告訴系統寫信人和寫信的內容就可以了, 別人會來看發信人是誰,如果不是自己想要的就放棄讀信或者只要有訊息自己就讀取訊息 訊息佇列就是按佇列的方式處理很多訊息,先發的最先被讀 訊息佇列:

Linux程序通訊訊息佇列

在上一篇部落格裡,我們學習了程序間通訊的一種方式,那就是管道,今天我們繼續學習另一種方式訊息佇列。 訊息佇列 一. 什麼是訊息佇列?   訊息佇列是訊息的連結串列,存放在核心中並由訊息佇列識別符號表示。   訊息佇列提供了一個從一個程序向另一個程

程序通訊訊息佇列和共享記憶體方式的實現

共享記憶體方式使用QSharedMemory 和QSystemSemaphore兩個類實現 一個程序往共享記憶體空間中寫,一個程序往共享記憶體空間中讀 兩程序通訊時: 向共享記憶體中提供資料的一方: 1,定義QSharedMemory shareMemory,並設定標誌名shareMemory.setKey(

Linux系統新增防火牆規則新增IP白名單

參考文件:防火牆的作用:    可以通過設定ip白名單/黑名單的方式限制外部ip的訪問或者限制訪問內部某個埠;新增防火牆過濾規則步驟如下;1、檢視現有防火牆過濾規則:    iptables -nvL --line-number2、新增防火牆過濾規則(設定白名單):