c语言编程之消息队列


//msg.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

#define MSGKEY 1000

struct msgStru
{
long msgType;
char msgText[4096];
};

main()
{
int iMsgId;
struct msgStru slQMsg,slRcvMsg;
int ilRc;

iMsgId = msgget(MSGKEY,IPC_EXCL);/*检查消息队列是否存在*/
if ( iMsgId < 0 ){
iMsgId = msgget(MSGKEY,IPC_CREAT|0666);/*创建消息队列*/
if ( iMsgId < 0 ){
printf("create msgQ error! errno=%d[%s]\n",errno,strerror(errno));
exit(-1);
}
}

slQMsg.msgType = 100;
strcpy(slQMsg.msgText,"Hello mcfeng.");
ilRc = msgsnd(iMsgId, &slQMsg, sizeof(struct msgStru),IPC_NOWAIT);
if( ilRc < 0 ) {
printf("msgsnd()写消息队列失败,errno=%d[%s]\n",errno,strerror(errno));
exit(-1);
}

ilRc = msgrcv(iMsgId,&slRcvMsg,sizeof(struct msgStru),0,0);/*接收消息队列*/
printf("text=[%s]\n",slRcvMsg.msgText);

msgctl(iMsgId,IPC_RMID,0); /* 删除消息队列 */
exit(0);
}




//receive.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>


#define MSGKEY 1024

struct msgstru
{
long msgtype;
char msgtext[2048];

};

main()
{
int imsgID;
struct msgstru slQMsg,slRcvMsg;
int ilrc;
char str[1024];


imsgID=msgget(MSGKEY,IPC_EXCL );//检查消息队列是否存在
if(imsgID < 0){
printf("消息不存在! errno=%d [%s]\n",errno,strerror(errno));
exit(-1);
}

ilrc = msgrcv(imsgID,&slRcvMsg,sizeof(struct msgstru),0,0);/*接收消息队列*/
printf("text=[%s]\n",slRcvMsg.msgtext);

msgctl(imsgID,IPC_RMID,0); //删除消息队列
exit(0);
}




//send.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>


#define MSGKEY 1024

struct msgstru
{
long msgtype;
char msgtext[2048];

};

main()
{
int imsgID;
struct msgstru slQMsg,slRcvMsg;
int ilrc;
char str[2048];

printf("请输入字符串:");
scanf ("%s",str);

imsgID=msgget(MSGKEY,IPC_EXCL ); //检查消息队列是否存在
if(imsgID < 0){
imsgID=msgget(MSGKEY,IPC_CREAT|0666);//创建消息队列
if(imsgID <0 ){
printf("创建消息失败! errno=%d [%s]\n",errno,strerror(errno));
exit(-1);
}
}

slQMsg.msgtype = 100;
strcpy(slQMsg.msgtext, str);
ilrc = msgsnd(imsgID,&slQMsg,sizeof(struct msgstru),IPC_NOWAIT); //发送消息队列
if ( ilrc < 0 ) {
printf("msgsnd()写消息队列失败,errno=%d[%s]\n",errno,strerror(errno));
exit(-1);

}
exit(0);

}



本程序实例介绍linux环境下利用消息队列进行进程间通信,主要介绍ftok函数,msgget创建消息队列和获取已存在消息队列,
msgctl获取消息队列结构信息,msgsnd发送消息到消息队列,msgrcv从消息队列中获取消息。

本程序由两个.c文件组成,msgQueueRecv.c和msgQueueSend.c,msgQueueRecv.c里面创建消息队列并阻塞式从消息队列接收消息,
最后删除消息队列(消息队列在内核创建);msgQueueSend.c获取以创建的消息队列,向消息队列发送消息。

请参考《unix环境高级编程》辅助学习。


//msgQueueRecv.c

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

#define BUFF_LEN 1024
#define RET_ERROR 1
#define RET_OK 0

int main()
{
char *pcPathName = "/"; /* pathname for ftok */
int iProjectId = 5; /* id for ftok */
key_t kId; /* key id */
struct msqid_ds stMsgInfo; /* msg queue info structure */
struct msgRecvStructure
{
long lMsgType; /* msg type */
char acMsgRecvBuff[BUFF_LEN]; /* send msg buffer */
}stMsgRecv;
int iRet;
int iMsgId; /* msg queue id */
int iFlag = IPC_CREAT | IPC_EXCL | 0666; /* msg queue creating flag */

/* build key using ftok function */
kId = ftok(pcPathName, iProjectId);
if ( kId == -1 )
{
printf("building key error, ftok() error!\n");
return RET_ERROR;
}
/* create msg queue */
iMsgId = msgget(kId, iFlag);
if ( iMsgId == -1 )
{
printf("create msg queue error, msgget() error!\n");
return RET_ERROR;
}

/* recv msg from msg queue */
iRet = msgrcv(iMsgId, &stMsgRecv, BUFF_LEN, 1, 0);
if ( iRet == -1 )
{
printf("msg recv error, msgrcv() error!\n");
msgctl(iMsgId, IPC_RMID, &stMsgInfo); /* delete msg queue from kernel */
return RET_ERROR;
}
else
{
printf("msg recv content: %s\n", stMsgRecv.acMsgRecvBuff);
}

msgctl(iMsgId, IPC_RMID, &stMsgInfo); /* delete msg queue from kernel */

return RET_OK;
}




msgQueueSend.c

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

#define BUFF_LEN 1024
#define RET_ERROR 1
#define RET_OK 0

int main()
{
char *pcPathName = "/"; /* pathname for ftok */
int iProjectId = 5; /* id for ftok */
key_t kId; /* key id */
struct msqid_ds stMsgInfo; /* msg queue info structure */
struct msgSendStructure
{
long lMsgType; /* msg type */
char acMsgSendBuff[BUFF_LEN]; /* send msg buffer */
}stMsgSend;
int iRet;
int iMsgId; /* msg queue id */
int iFlag = 0666; /* msg queue creating flag */

/* build key using ftok function */
kId = ftok(pcPathName, iProjectId);
if ( kId == -1 )
{
printf("building key error, ftok() error!\n");
return RET_ERROR;
}
/* get existing msg queue */
iMsgId = msgget(kId, iFlag);
if ( iMsgId == -1 )
{
printf("get msg queue error, msgget() error!\n");
return RET_ERROR;
}

/* send msg to msg queue */
stMsgSend.lMsgType = 1;
strcpy(stMsgSend.acMsgSendBuff, "hello,world");
iRet = msgsnd(iMsgId, &stMsgSend, strlen("hello,world")+1, IPC_NOWAIT);
if ( iRet == -1 )
{
printf("msg send error, msgsnd() error!\n");
return RET_ERROR;
}

return RET_OK;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面给出一个简单的例子。 首先,我们需要定义一个消息的结构体,包含消息的类型和内容: ```c struct message { long type; char content[1024]; }; ``` 然后,我们需要创建两个进程,一个用来发送消息,一个用来接收消息。在这两个进程中,我们都需要创建一个消息队列,用来存储消息。 ```c #include <sys/msg.h> #include <stdio.h> #include <stdlib.h> int main() { int msgid; struct message msg; // 创建消息队列 msgid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT); if (msgid == -1) { perror("msgget"); exit(1); } // 发送消息 msg.type = 1; // 消息类型为1 sprintf(msg.content, "%s", "Hello, world!"); if (msgsnd(msgid, &msg, sizeof(msg.content), 0) == -1) { perror("msgsnd"); exit(1); } // 接收消息 if (msgrcv(msgid, &msg, sizeof(msg.content), 0, 0) == -1) { perror("msgrcv"); exit(1); } printf("Received message: %s\n", msg.content); // 删除消息队列 if (msgctl(msgid, IPC_RMID, NULL) == -1) { perror("msgctl"); exit(1); } return 0; } ``` 上面的代码中,我们首先创建了一个消息队列,然后在发送进程中,将消息的类型设为1,内容为"Hello, world!",并发送到消息队列中。在接收进程中,我们从消息队列中读取消息,并打印出来。最后,我们删除消息队列。 注意,在创建消息队列时,我们使用了IPC_PRIVATE作为键值,这意味着这个消息队列只能被创建进程和其子进程访问。如果我们想要在两个独立的进程中使用同一个消息队列,我们需要使用一个已知的键值,比如ftok函数生成的键值。另外,我们还需要注意消息的大小,要确保发送和接收进程中使用的消息大小一致。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值