linux進程通信之消息隊列

消息隊列:

類似於有名管道,使用消息隊列的進程也不必具備親緣關係,任意兩個進程間均可以使用消息隊列通信。

不過消息隊列獨立於發送和接收的進程,因此就不必考慮同步的問題,這一點相對有名管道而言是一個優勢。

消息隊列以數據塊傳送數據,每個數據塊是一個以長整型開頭的結構體。

消息隊列的幾個方法如下:

int msgget(key_t key, int msgflg);

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">此方法成功執行會返回新的消息隊列描述符,否則返回-1.key是和描述符相關的鍵值,當key是IPC_PRIVATE時,會返回一個新私有隊列的描述符,理論上只能當前進程訪問。當key是一個普通的鍵值時,方法會返回key值對應的隊列描述符,當隊列不存在時,而msgflg制定了IPC_CREAT,方法會返回一個與該鍵值相關的新的描述符。所以msgflag是權限標誌,一般情況都和IPC_CREAT做或操作。</span>

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

此方法是控制消息隊列的方法。msqid就是上一個方法返回的描述符,cmd是對消息隊列所進行的操作

IPC_STAT  把消息隊列的關聯值複製到buf

IPC_SET    把消息隊列的關聯值設置爲buf指向的值

IPC_RMID  刪除消息隊列


<span style="font-size:18px;">int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);</span>


此方法向消息隊列添加消息,msgp是一個執行消息結構體的指針。消息結構體必須定義成如下格式:

struct my_mess{
    long int mess_type;
    char my_text[SIZE];
};

msgsz是數據塊的大小,msgflg用於控制當前消息隊列滿或者隊列消息到達系統範圍的限制時將要發生的事情。

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


此方法接收來自msqid隊列的消息,msftyp是消息結構中的long型參數。

下面是一個小案例:

messsend.c

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

#define SIZE 1024

struct my_mess{
    long int mess_type;
    char my_text[SIZE];
};
void main(){
    int mess_id;
    char buff[SIZE];
    struct my_mess mess;
    mess_id=msgget((key_t)1234,0666|IPC_CREAT);
    if(mess_id==-1){
        printf("create message failed!\n");
        exit(EXIT_FAILURE);
    }

    while(1){
        printf("send>> ");
        fgets(buff,SIZE,stdin);
        mess.mess_type = 1;
        strcpy(mess.my_text,buff);
        if(msgsnd(mess_id,(void *)&mess,SIZE,0)==-1){
            printf("send message failed!\n");
            exit(EXIT_FAILURE);
        }
        if(strncmp(buff,"quit",4)==0)break;
    }
    exit(EXIT_SUCCESS);
}


messreceive.c

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

#define SIZE 1024
struct my_mess_t{
    long int my_mess_type;
    char mess_text[SIZE];
};
void main(){
    struct my_mess_t mess;
    int mess_id;
    char buff[SIZE];
    long int mess_rec = 0;
    mess_id = msgget((key_t)1234,0666|IPC_CREAT);
    if(mess_id==-1){
        printf("create message error!\n");
        exit(EXIT_FAILURE);
    }
    while(1){
        if(msgrcv(mess_id,&mess,SIZE,mess_rec,0)==-1){
            printf("receive mess failed!\n");
            exit(EXIT_FAILURE);
        }
        printf("receive:%s",mess.mess_text);
        if(strncmp(mess.mess_text,"quit",4)==0)break;
    }
    if(msgctl(mess_id,IPC_RMID,0)==-1){
        printf("delete mess failed!\n");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

執行結果:



以上內容參考博客:

http://blog.csdn.net/ljianhui/article/details/10287879,不對之處還請大家批評指正!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章