一 消息隊列
消息隊列就是一些消息的清單,使用者可以在消息隊列中添加消息和讀取消息燈。消息隊列具有一定的FIFO特性,但是它可以實作消息的随機查詢,比FIFO更具有優勢。同時,這些消息又是存在于核心中的,由“隊列ID”來辨別。
二 函數學習
三 執行個體
在該執行個體當中,發送端發送的消息類型設定為該程序的程序号(也可以取其他值),是以接受端根據消息類型來确定消息發送者的程序号。
messagesend.c
//使用消息隊列發送資訊
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#define BUFF_SIZE 512
struct message{
long msg_type;
char msg_text[BUFF_SIZE];
};
void main()
{
key_t key=0;
int qid;
struct message msg;
if( (key=ftok(".",'a')) == -1)
{
//建立鍵值失敗
printf("creat key error\n");
exit(0);
}
//建立消息隊列
/*****************************
函數原型:int msgget(key_t key,int msgflg)
函數參數:key 消息隊列的鍵值,多個程序通過它通路一個消息
隊列
msgflg 權限标志位
傳回值:成功 傳回消息隊列的ID
失敗 傳回-1
*****************************/
if((qid=msgget(key,IPC_CREAT|0666))==-1)
{
printf("msgget\n",-1);
exit(0);
}
//列印消息隊列的ID
printf("open queue %d\n",qid);
while(1)
{
printf("Enter some message to the queue:\n");
if((fgets(msg.msg_text,BUFF_SIZE,stdin))==NULL)
{
printf("no message\n");
exit(1);
}
msg.msg_type=getpid();
/*****************************
函數原型:int msgsnd(int msqid,
const void *msqp,
size_t msgsz,
int msgflg)
函數參數: msqid 消息隊列的id
msqp 指向消息結構的指針,該消息結構msgbuf通常如下
struct msgbuf
{
long mtype; //消息類型,該結構必須從這個域開始
char mtext[];//消息正文
}
msgsz 消息正文的位元組數(不包括消息類型指針變量)
msgflg IPC_NOWAIT:若消息無法立即發送,函數會立刻傳回
0 msgsnd:調用阻塞直到發送成功為止
傳回值: 成功 0
失敗 -1
*****************************/
if(msgsnd(qid,&msg,strlen(msg.msg_text),0)==-1)
{
printf("msgsnd error\n");
exit(0);
}
if(strncmp(msg.msg_text,"quit",4)==0)
{
break;
}
}
exit(0);
}
messagereceive.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#define BUFF_SIZE 512
struct message{
long msg_type;
char msg_text[BUFF_SIZE];
};
void main()
{
int qid;
key_t key;
struct message msg;
if( (key=ftok(".",'a')) == -1)
{
//建立鍵值失敗
printf("creat key error\n");
exit(0);
}
if((qid=msgget(key,IPC_CREAT|0666))==-1)
{
printf("msgget\n",-1);
exit(0);
}
//列印消息隊列的ID
printf("open queue %d\n",qid);
do
{
/************************
函數原型:void *memset(void *s, int ch, size_t n);
函數描述:将s中目前位置後面的n個位元組 (typedef unsigned int size_t )用 ch 替換并傳回 s
************************/
memset(msg.msg_text,0,BUFF_SIZE);
/*讀取消息隊列*/
/********************
函數原型:ssize_t msgrcv(int msqid,
void *msgp,
size_t msgsz,
long msgtyp,
int msgflg)
函數參數:msqid 消息隊列的ID
msgp 消息緩沖區,通msgsnd()函數的msgp
msgsz 消息正文的位元組數 (不包括消息類型指針變量)
msgtyp 0 接受消息隊列中的第一個消息
大于0 接受消息隊列中第一個類型為msgtyp的消息
小于0 接受消息隊列中第一個類型值不小于msgtyp絕對值且類型值最小的消息
msgflg 0 msgsnd()調用阻塞直到接受一條相應類型的消息為止
函數傳回值:成功 0
失敗 -1
********************/
if(msgrcv(qid,(void *)&msg,BUFF_SIZE,0,0)<0)
{
printf("msgrcv\n");
exit(0);
}
printf("the message from %d:%s",msg.msg_type,msg.msg_text);
}while(strncmp(msg.msg_text,"quit",4));
//删除消息隊列
/*
函數原型:int msgctl(int msgqid,int cmd,struct msgqid_ds *buf)
函數參數:msgqid 消息隊列的隊列id
cmd IPC_STAT 讀取消息隊列的資料結構msqid_ds,并将其存儲在buf指定的位址中
IPC_SET 設定消息隊列的資料結構msqid_ds中的ipc_perm域值,這個值取自buf參數
IPC_RMID 從核心中删除消息隊列
buf 描述消息隊列的msqid_ds結構類型變量
傳回值:
*/
if(msgctl(qid,IPC_RMID,NULL)<0)
{
printf("msgctl\n");
exit(0);
}
}
運作結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICdzFWRoRXdvN1LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90EROVTSU1kejpWTmZEWjZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jM1cDO0ITN2EjNxEDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)