1. 程式人生 > >IPC——應用三 訊息佇列

IPC——應用三 訊息佇列

 

目錄

一:訊息佇列

1.1定義

1.2設計方案

 

1.3知識瞭解

二:程式碼實現

2.1傳送訊息

2.2取用訊息

2.3測試執行


 


一:訊息佇列

1.1定義

             訊息佇列是訊息的連結表,儲存在核心中,由訊息佇列識別符號 標識。

1.2設計方案

          如圖所示:先呼叫msgget()獲取一個已存在,或者 建立一個新的佇列。A程序負責傳送某一型別的資料,B程序負責接受相應型別的資料。

 

1.3知識瞭解

      一:相關結構

        ①訊息結構:

//假設傳送的最長訊息是512個位元組
struct mymesg{
    long mtype; /* positive message type */
    char mtext[512]; /*message data, or length nbytes */
}

        ②每個訊息佇列都會維護一個相關資料結構: msqid_ds

//訊息佇列維護資訊。
struct msqid_ds{
    struct ipc_perm     msg_perm;  //許可權控制
    msgqnum_t           msg_qnum;  //訊息佇列訊息數目
    msglen_t            msg_qbytes;//max # of bytes on queue
    pid_t               msg_lspid; //pid of last msgsnd()上一次傳送訊息的程序
    pid_t               msg_lrpid; //pid of lase msgrcv()上一次接受訊息的程序
    time_t              msg_stime; //last_msgsnd() time

    time_t              msg_rtime; //last_ecvsnd() time
    time_t              msg_ctime; //last_change time
}
    

        二:相關函式

            ①函式:msgget

標頭檔案 函式原型:

#include<sys/msg.h> 

int msgget(key_t key,int flag)

引數:

key:用於變換成一個識別符號(ID)

flag:許可權,以及各種控制資訊的指定。

功能: 建立一個新佇列或者開啟一個現有佇列。(主要是和其他函式配套使用,msgctl,msgsnd,msgrcv)。
函式返回值: 成功返回訊息佇列ID,出錯返回-1.

       


            ②函式:msgctl

函式原型: int msgctl ( int msgid, int cmd , struct msqid_ds *buf);
函式引數:

1 msgid :佇列編號

2 cmd :(幻數),用於指定命令,IPC_STAT,IPC_SET,IPC_RMID.

3 buf:指向結構體的指標。

函式功能: 對佇列進行多種操作。

          ③函式:msgsnd

函式原型 int msgsnd ( int msgid , const void* ptr , size_t nbytes , int flag)
函式引數:

1 msgid:佇列編號

2 ptr :指向一個mesg的結構體(本結構體不是標頭檔案提供的

3 nbytes: 訊息大小。

4 flag(幻數),用於指定命令,IPC_NOWAIT(非阻塞標誌)。

函式功能和返回值:

將資料傳送到訊息佇列中:

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


        ④函式:msgrcv

函式原型: int msgrcv ( int msgid , void* ptr , size_t nbytes,long type , int flag);
函式引數:

msgid 佇列編號

ptr 指向一個mesg結構體指標

nbytes 訊息大小

type 訊息型別

flag(幻數) 用於制定命令,IPC_NOWAIT(非阻塞標誌)。

函式功能和返回值: 從訊息佇列中取資料。 成功,返回訊息佇列資料部分的長度,否則返回-1。

二:程式碼實現

2.1傳送訊息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/msg.h>


typedef struct  data
{
	long type;
	char text[512];
}Data;


int main()
{
	int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);//獲取
	assert(msgid != -1);


	Data val;
	memset(&val, 0, sizeof(Data));
	val.type = 1000;
	strcpy(val.text, "hello");

	msgsnd(msgid, &val, strlen(val.text)+sizeof(val.type), 0);
	
	memset(&val, 0, sizeof(Data));
	val.type = 2000;
	strcpy(val.text, "world");

	msgsnd(msgid, &val, strlen(val.text)+sizeof(val.type), 0);

	exit(0);
}

2.2取用訊息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/msg.h>


typedef struct  data
{
	long type;
	char text[512];
}Data;


int main()
{
	int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
	assert(msgid != -1);


	Data val;
	memset(&val, 0, sizeof(Data));

	//char buff[128] = {0};

	msgrcv(msgid, &val, sizeof(Data), 1000, 0);

	printf("type = %d, text = %s\n", val.type, val.text);

	exit(0);
}

2.3測試執行