Linux下的消息队列msgrcv实现及应用 (linux消息队列msgrcv)

Linux操作系统是一种开源的操作系统,被广泛应用于各种服务器和嵌入式设备中。在企业应用中,消息队列是一种常见的进程间通信方式,很多企业系统都是基于消息队列实现各个模块之间的数据传输和协调。Linux系统提供了一种称为msgrcv的函数用于进程间消息队列的接收和处理。本文将着重介绍。

一、消息队列的概念

消息队列是一种进程间通信方式,它是消息的链表,存放在内核中。消息队列中的每个消息都有一个消息类型和消息体。消息类型用于标识消息的用途,消息体则是真正的数据部分。

消息队列是多个进程共享的一种数据结构,通过消息队列,发送方可以把消息发送到消息队列中,接收方则从消息队列中读取消息并进行处理。在使用消息队列时,发送方和接收方可以是同一个进程,也可以是不同的进程。

二、msgrcv函数的实现

在Linux系统中,进程间通信的方式有多种,比如信号、管道、共享内存等。消息队列是其中一种较为高效的方式。在Linux系统中,进程通过定义特定的消息类型和消息内容,将消息发送到消息队列中,而通过msgrcv函数则可以从消息队列中读取并处理消息。

在Linux系统中,msgrcv函数是一个系统调用函数,其完整定义如下:

“`

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

“`

函数各参数含义如下:

msqid:消息队列的标识符,它是通过msgget函数创建消息队列后返回的一个值。

msgp:消息的接收缓冲区指针。调用msgrcv函数后,内核将消息从消息队列中读取到该缓冲区中。

msgsz:接收缓冲区的大小,msgsz应该至少等于消息长度。

msgtyp:指定所读取消息的消息类型。其值为0时,可以读取消息队列中的之一条消息;否则,值为msgtyp的消息将被读取。

msg:消息的接收方式。它可以取以下值:

– IPC_NOWT:如果消息队列中没有符合要求的消息,则返回-1,并将errno设置为ENOMSG。

– MSG_NOERROR:如果消息长度超过msgsz,则被截断。

– MSG_EXCEPT:读取类型为msgtyp以外所有类型的消息,而不是读取类型为msgtyp的消息。

– MSG_COPY:读取类型为msgtyp的消息时,内核将消息从消息队列中移除,并将其复制到msgp中,而不是返回一个指向缓冲区的指针。

三、msgrcv函数的使用

使用msgrcv函数可以很方便地从消息队列中读取并处理消息。下面是一个示例程序,通过msgrcv函数从消息队列中读取消息并输出消息体的内容。

创建消息队列及发送消息:

“`

#include

#include

#include

#include

#define MSG_KEY 0x12345678

int mn()

{

int msgid;

struct msgbuf {

long mtype;

char mtext[256];

} message;

// 创建消息队列

msgid = msgget(MSG_KEY, IPC_CREAT | 0666);

if (msgid == -1) {

perror(“msgget”);

exit(EXIT_FLURE);

}

// 发送消息

message.mtype = 1;

snprintf(message.mtext, 256, “Hello, world!”);

if (msgsnd(msgid, &message, sizeof(message), 0) == -1) {

perror(“msgsnd”);

exit(EXIT_FLURE);

}

return 0;

}

“`

上述程序使用msgget函数创建了一个消息队列,并通过msgsnd函数向消息队列中发送了一条消息。

下面是使用msgrcv函数读取消息的示例程序:

“`

#include

#include

#include

#include

#define MSG_KEY 0x12345678

int mn()

{

int msgid;

struct msgbuf {

long mtype;

char mtext[256];

} message;

// 连接消息队列

msgid = msgget(MSG_KEY, 0666);

if (msgid == -1) {

perror(“msgget”);

exit(EXIT_FLURE);

}

// 从队列中读取消息

if (msgrcv(msgid, &message, sizeof(message), 1, 0) == -1) {

perror(“msgrcv”);

exit(EXIT_FLURE);

}

printf(“Received message: %s\n”, message.mtext);

return 0;

}

“`

上述程序使用msgget函数打开消息队列,并通过msgrcv函数从消息队列中读取了一条消息,并输出消息内容。

四、消息队列的应用场景

消息队列广泛应用于各种企业系统中,例如电商系统、银行系统、物流系统等。下面简要介绍消息队列在这些系统中的应用场景。

1. 电商系统

在电商系统中,消息队列可以用于记录日志信息,并对于不同类型的操作建立不同的消息类型,例如订单、库存、日志等。消息队列中的每条消息可以包含订单编号、日志信息、库存信息等,并通过消息队列传递给其他模块进行处理。

2. 银行系统

在银行系统中,消息队列可以用于处理交易信息,例如客户向银行申请贷款、转账等操作。对于每个交易,银行会对其进行处理并返回相应的结果,所有的交易信息都可以通过消息队列进行传递,提高交易处理的速度和效率。

3. 物流系统

在物流系统中,消息队列可以用于处理订单信息、运输信息等。例如,每个订单都会有一个唯一的订单号,订单信息会通过消息队列传递给相应的快递员,快递员在途中需要不断更新订单的状态,例如已发货、已派送等。所有这些状态信息都可以通过消息队列进行交换和传递。

五、

相关问题拓展阅读:

如何在linux下看消息队列是否存在

#include

#include

#include

#include types.h>

#include msg.h>

#include

#include ipc.h>

void msg_show_attr(int msg_id, struct msqid_ds msg_info)

{

int ret = -1;

sleep(1);

ret = msgctl(msg_id, IPC_STAT, &msg_info);

if( -1 == ret)

{

printf(获消息信息失败\n);

return ;

}

printf(\n);

printf(现队列字节数:%d\n,msg_info.msg_cbytes);

printf(队列消息数:%d\n,msg_info.msg_qnum);

printf(队列字节数:%d\n,msg_info.msg_qbytes);

printf(发送消息进程pid:%d\n,msg_info.msg_lspid);

printf(接收消息进程pid:%d\n,msg_info.msg_lrpid);

printf(发送消息间:%s,ctime(&(msg_info.msg_stime)));

printf(接收消息间:%s,ctime(&(msg_info.msg_rtime)));

printf(变化间:%s,ctime(&(msg_info.msg_ctime)));

printf(消息UID:%d\n,msg_info.msg_perm.uid);

printf(消息GID:%d\n,msg_info.msg_perm.gid);

}

int main(void)

{

int ret = -1;

int msg_flags, msg_id;

key_t key;

struct msgmbuf{

int mtype;

char mtext;

};

struct msqid_ds msg_info;

struct msgmbuf msg_mbuf;

int msg_sflags,msg_rflags;

char *msgpath = /ipc/msg/;

key = ftok(msgpath,’a’);

if(key != -1)

{

printf(功建立KEY\n);

}

else

{

printf(建立KEY失败\n);

}

msg_flags = IPC_CREAT;

msg_id = msgget(key, msg_flags|0666);

if( -1 == msg_id)

{

printf(消息建立失败\n);

return 0;

}

msg_show_attr(msg_id, msg_info);

msg_sflags = IPC_NOWAIT;

msg_mbuf.mtype = 10;

memcpy(msg_mbuf.mtext,测试消息,sizeof(测试消息));

ret = msgsnd(msg_id, &msg_mbuf, sizeof(测试消息), msg_sflags);

if( -1 == ret)

{

printf(发送消息失败\n);

}

msg_show_attr(msg_id, msg_info);

msg_rflags = IPC_NOWAIT|MSG_NOERROR;

ret = msgrcv(msg_id, &msg_mbuf, 10,10,msg_rfla

共享内存示例代码:

#include

#include sem.h>

#include ipc.h>

#include

typedef int sem_t;

union semun {

int val;

struct semid_ds *buf;

unsigned short *array;

} arg;

sem_t CreateSem(key_t key, int value)

{

union semun sem;

sem_t semid;

sem.val = value;

semid = semget(key,value,IPC_CREAT|0666);

if (-1 == semid)

{

printf(create semaphore error\n);

return -1;

}

semctl(semid,0,SETVAL,sem);

return semid;

}

/*

struct sembuf{

ushort sem_num;

short sem_op;

short sem_;

};

*/

void SetvalueSem(sem_t semid, int value)

{

union semun sem;

sem.val = value;

semctl(semid,0,SETVAL,sem);

return ;

}

int GetvalueSem(sem_t semid)

{

union semun sem;

return semctl(semid,0,GETVAL,sem);

return sem.val;

}

void DestroySem(sem_t semid)

{

union semun sem;

sem.val = 0;

semctl(semid,0,IPC_RMID,sem);

}

int Sem_P(sem_t semid)

{

struct sembuf sops={0,+1,IPC_NOWAIT};

return (semop(semid,&sops,1));

}

int Sem_V(sem_t semid)

{

struct sembuf sops={0,-1,IPC_NOWAIT};

return (semop(semid,&sops,1));

}

static char msg=共享内存\n;

int main(void)

{

key_t key;

int semid,shmid;

char i,*shms,*shmc;

struct semid_ds buf;

int value = 0;

char buffer;

pid_t p;

key = ftok(/ipc/sem/,’a’);

shmid = shmget(key,1024,IPC_CREAT|0604);

semid = CreateSem(key,1);

p = fork();

if(p > 0)

{

/* 父进程 */

/* 建立共享内存 */

shms = (char *)shmat(shmid,0,0);

memcpy(shms, msg, strlen(msg)+1);

sleep(10);

Sem_P(semid);

shmdt(shms);

DestroySem(semid);

}

else if(p == 0)

{

shmc = (char *)shmat(shmid,0,0);

Sem_V(semid);

printf(共享内存值:%s\n,shmc);

linux消息队列msgrcv的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux消息队列msgrcv,Linux下的消息队列msgrcv实现及应用,如何在linux下看消息队列是否存在的信息别忘了在本站进行查找喔。


数据运维技术 » Linux下的消息队列msgrcv实现及应用 (linux消息队列msgrcv)