1. Introdução à fila de mensagens:
Uma fila de mensagens é uma lista de mensagens. Os usuários podem adicionar informações de leitura e gravação na fila de mensagens. E a mensagem é armazenada no kernel, identificada pelo ID da fila, e é um tipo de objeto IPC. As filas de mensagens podem enviar/receber mensagens por tipo.
Características: Fila: primeiro a entrar, primeiro a sair.
2. APIs relacionadas:
2.1 Crie ou obtenha uma fila de mensagens:
mensagemgget()
msgget
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
功能:
创建或获取消息队列
参数:
key:参考共享内存中key详解
msgflg:IPC_CREAT|0666
返回值:
成功返回消息队列ID
失败返回-1,并设置错误码
2.2 Grave dados na fila de mensagens:
msgsnd
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:
往消息队列中写入数据
参数:
1>msqid:消息队列的ID
2>msgp:结构体指针:
struct msgbuf {
long mtype; /* message type, must be > 0 */必须大于0
char mtext[1]; /* message data */
};//这个结构体可以直接用,但是不好用
3>msgsz:正文的大小 (除去类型)
最简单:sizeof(struct msgbuf)-sizeof(long);
4>msgflg: 0 可阻塞
IPC_NOWAIT 不阻塞
返回值:
成功返回0
失败返回-1,并设置错误码
2.3 Ler dados
msgrcv
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
功能:
读取数据(按照类型)
参数:
1>msqid:消息队列的ID
2>msgp:结构体指针:
struct msgbuf {
long mtype; /* message type, must be > 0 */必须大于0
char mtext[1]; /* message data */
};//
3>msgsz:正文的大小 (除去类型)
最简单:sizeof(struct msgbuf)-sizeof(long);
也可以: strlen(mtext);
4>msgtyp:读取的方式:
=0:读取整个队列的第一条数据
>0:读取对应类型的第一条数据
<0
5>msgflg:0 可阻塞
IPC_NOWAIT 不阻塞
返回值:
成功返回读取的正文大小
失败返回-1,并设置错误码
2.4 Exclua a fila de mensagens:
msgctl
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:
对消息队列操作
参数:
msqid:消息队列ID
cmd:选项
IPC_RMID:删除操作
buf:结构体指针:会随着选项的改变而选择值
IPC_RMID:NULL
返回值:
成功返回0
失败返回-1,并设置错误码
3. Visualize a fila de mensagens:
Como visualizar a fila de mensagens em nosso sistema?
ipcs -q
Use o comando para excluir a fila de mensagens no sistema
ipcrm -q ID da fila de mensagens
Os pontos principais da fila de mensagens:
1> Use conceitos especiais para armazenar dados temporariamente
2> Os dados são gravados e lidos com base no conceito de fila
4. Implementação de fila de mensagens
Ler dados:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf {
long mtype; /* message type, must be > 0 *///必须大于0
char mtext[100]; /* message data *///随便写什么:为所欲为
};
int main(){
//1>创建和获取消息队列
//前提:创建key
key_t key=ftok("1.c",1);
if(key<0){
perror("ftok");
return -1;
}
printf("key:%#x\n",key);
//创建消息队列
int msgid=msgget(key,IPC_CREAT|0666);
if(msgid<0){
perror("msgget");
return -1;
}
printf("消息队列的ID号为:%d\n",msgid);
//2>读取数据
struct msgbuf xr;
int ret=msgrcv(msgid,&xr,sizeof(struct msgbuf)-sizeof(long),-5,0);
if(ret<0){
perror("msgsnd");
return -1;
}
printf("%s\n",xr.mtext);
return 0;
}
entrada de dados:
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf {
long mtype; /* message type, must be > 0 *///必须大于0
char mtext[100]; /* message data *///随便写什么:为所欲为
};
int main(){
//1>创建和获取消息队列
//前提:创建key
key_t key=ftok("1.c",1);
if(key<0){
perror("ftok");
return -1;
}
printf("key:%#x\n",key);
//创建消息队列
int msgid=msgget(key,IPC_CREAT|0666);
if(msgid<0){
perror("msgget");
return -1;
}
printf("消息队列的ID号为:%d\n",msgid);
//2>写入数据
struct msgbuf xr;
xr.mtype=5;//消息队列中类型为1;
strcpy(xr.mtext,"孙笑川");//二次赋值:scanf 或者 strcpy
int ret=msgsnd(msgid,&xr,sizeof(struct msgbuf)-sizeof(long),0);
if(ret<0){
perror("msgsnd");
return -1;
}
//3>删除消息队列
ret=msgctl(msgid,IPC_RMID,NULL);
if(ret<0){
perror("msgctl");
return -1;
}
return 0;
}