【问题标题】:Message too long - buffer is larger than message size消息太长 - 缓冲区大于消息大小
【发布时间】:2016-12-07 01:19:22
【问题描述】:

我正在尝试自学消息队列,并且我正在使用相互通信的 pthread。 我知道 mq_receive 中的缓冲区应该大于 attr.mq_msgsize,并且是(大小的两倍)。 我还没发消息呢。

编辑:John Bollinger 在他的机器上运行了这个程序,并且成功了。这可能是依赖于操作系统的问题。我正在运行 Mint 18 XFCE

编辑编辑:重新启动修复了行为?不会对此提出质疑或抱怨。

此代码基于我在网上找到的示例:https://github.com/arembedded/mq_example

代码如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <fcntl.h>
#include <errno.h>


using namespace std;

#define PIN_MSG_NAME "/pin_msg"
#define DB_MSG_NAME "/db_msg"

#define MESSAGE_QUEUE_SIZE 15

pthread_t ATM;
pthread_t DB_server;
pthread_t DB_editor;
void* run_ATM(void* arg);
void* run_DB(void* arg);

static struct mq_attr mq_attribute;
static mqd_t PIN_MSG = -1;

void sig_handler(int signum){
    //ASSERT(signum == SIGINT);
    if (signum == SIGINT){
        cout << "killing application" << endl;

        pthread_cancel(ATM);
        pthread_cancel(DB_server);
        pthread_cancel(DB_editor);
    }
}

int main(int argc, char const *argv[])
{
    pthread_attr_t attr;

    signal(SIGINT, sig_handler);

    mq_attribute.mq_maxmsg = 10; //mazimum of 10 messages in the queue at the same time
    mq_attribute.mq_msgsize = MESSAGE_QUEUE_SIZE;

    PIN_MSG = mq_open(PIN_MSG_NAME , O_CREAT | O_RDWR, 0666, &mq_attribute);
    if (PIN_MSG == -1){
        perror("creating message queue failed ");
    }

    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, 1024*1024);

    long start_arg = 0; //the start argument is unused right now
    pthread_create(&ATM, NULL, run_ATM, (void*) start_arg);
    pthread_create(&DB_server, NULL, run_DB, (void*) start_arg);

    pthread_join(ATM, NULL);
    pthread_join(DB_server, NULL);

    sig_handler(SIGINT);
}

void* run_ATM(void* arg) {
    int status;
    char accountNumber[15];
    char PIN[15];

    cout << "ATM is running" << endl;
    cout << "Please input an account number > ";
    cin >> accountNumber;
    status = mq_send(PIN_MSG, accountNumber, sizeof(accountNumber) + 1, 1);
    if (status < 0){
        perror("sending message failed");
    }
}

void* run_DB(void* arg){
    cout << "Database server running" << endl;
    int status;
    char received_acct_number[30];

    while(1){
        status = mq_receive(PIN_MSG, received_acct_number, sizeof(received_acct_number), NULL);
        if (status < 0){
            perror("error:");
        } else {
            cout << received_acct_number << endl;
        }
    }
}

我错过了什么吗?为什么有消息进来,为什么它太大了?

【问题讨论】:

  • 这更像是 C 而不是 C++。 :)
  • 你是对的 - 更改了标签
  • 那里有一个cout(和iostream)使它成为c++,但问题更多的是c问题。
  • 其实有很多 C++ I/O,包括 C++ 风格的#include &lt;iostream&gt;,还有一个using 语句。我没有看到任何获得的东西,但目前,代码是无效的 C.
  • 这是 libc 问题而不是 C。

标签: c message-queue


【解决方案1】:

您谈论您的接收缓冲区大小,就好像mq_receive() 报告了错误一样,但是正如您所观察到的,您的缓冲区足够长,可以接收可以在您的队列中排队的任何消息,而且,您似乎没有完全期待收到的消息。

虽然我不确定你怎么会这样混淆,但我倾向于认为问题出现在发送消息:

char accountNumber[15];

...

status = mq_send(PIN_MSG, accountNumber, sizeof(accountNumber) + 1, 1);

您的队列的消息长度限制为 15 个字节,而您正在尝试将 16 个字节的消息加入队列。此外,您的发送缓冲区实际上首先短于 16 个字节;如果mq_send() 试图复制 16 字节的消息,那么这将产生未定义的行为。

【讨论】:

  • 我遇到的问题是代码尚未到达。 cin 应该阻塞并等待用户输入。 mq_send 永远不会运行,所以我不希望消息已经到达。
  • @BrydonGibson,您认为cin 应该 做的事情与实际做的事情之间似乎存在差异。您的消息发送代码肯定有问题,而且这是我在您的程序中看到的唯一一个看起来可能是您报告的错误来源的候选。
  • 消息发送代码中没有循环 - 为什么接收方不是 1) 在收到第一条消息后阻塞和 2) 总是说“消息太长”?最坏的情况,应该发送一次错误消息,然后 ATM 退出。
  • @BrydonGibson,还请注意,对我来说,您的程序在报告消息太长错误之前确实会等待我输入帐号。
  • @BrydonGibson,正如我在回答中所说,不是 receiver 报告消息太长,而是 sender。我自己对你的程序的测试证实了这一点。
猜你喜欢
  • 2013-09-01
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
相关资源
最近更新 更多