首页 > 解决方案 > C/C++ - 消息队列在同一 mtype 上发送和接收消息

问题描述

我正在使用我自己的 C 消息队列封装。我可以发送尽可能多的消息,并且接收相同的消息。但是,当我试图从“发送者”进程接收消息并从“接收”进程发送消息时,它会message from the "sender" process永远发送我的和循环。我对这个问题的解决方案是通过使用std::this_thread::sleep_for(std::chrono::milliseconds(5));. 我的问题是:我怎样才能重现相同的结果但没有延迟?

这是我的代码:

msgqueue.cpp

#include "msgqueue.hpp"

MsgQueue::MsgQueue(key_t key)
{
    this->_key = key;
    this->Create();
}

MsgQueue::~MsgQueue()
{
}

int MsgQueue::Create(void)
{
    this->_msgid = msgget(this->_key, IPC_CREAT|0666);
    if (this->_msgid < 0) {
        perror("msgget");
        return 84;
    }
    return 0;
}

void MsgQueue::Close()
{
    msgctl(this->_msgid, IPC_RMID, nullptr);
}

int MsgQueue::Send(std::string msg)
{
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
    this->_buff.mtype = 1;
    bzero(this->_buff.mtext, MSGSZ);
    strncpy(this->_buff.mtext, msg.c_str(), MSGSZ - 1);
    if (msgsnd(this->_msgid, &this->_buff, MSGSZ, 0) < 0) {
        perror("msgsnd");
        return 84;
    }
    return 0;
}

std::string MsgQueue::Receive()
{
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
    this->_buff.mtype = 0;
    bzero(this->_buff.mtext, MSGSZ);
    if (msgrcv(this->_msgid, &this->_buff, MSGSZ, 0, 0) < 0) {
        perror("msgrcv");
        return "";
    }
    return std::string(this->_buff.mtext);
}

消息队列.hpp

#ifndef MSG_QUEUE_
#define MSG_QUEUE_

extern "C" {
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
}

#include <cstring>
#include <string>
#include <thread>
#include <chrono>
#include <iostream>

#define MSGSZ 256

class MsgQueue
{
    public:
        MsgQueue(key_t key);
        ~MsgQueue();
        int Create(void);
        void Close(void);
        int Send(std::string msg);
        std::string Receive(void);

    public:
        struct msgbuff {
            long mtype;
            char mtext[MSGSZ];
        };

    private:
        struct msgbuff _buff = {0, {0}};
        int _msgid;
        key_t _key;
};
#endif

和一个主要的测试它

#include "msgqueue.hpp"
#include <iostream>

int main(void)
{
    MsgQueue myQueue(65);

    pid_t child;
    int wstatus;

    child = fork();
    if (child < 0)
        return 84;
    if (child == 0) {
        std::cout << myQueue.Receive() << std::endl;
        myQueue.Send("This is it !");
        myQueue.Send("Hey !");
        exit(0);
    } else {
        myQueue.Send("LOUL");
        std::cout << myQueue.Receive() << std::endl;
        std::cout << myQueue.Receive() << std::endl;
        waitpid(child, &wstatus, 0);
    }
    myQueue.Close();
    return 0;
}

标签: c++cmessage-queueencapsulation

解决方案


推荐阅读