消息太长 - 缓冲区大于消息大小

时间:2016-12-06 14:34:18

标签: c message-queue

我试图教自己消息队列,而且我使用互相交谈的pthreads。 我知道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;
        }
    }
}

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

1 个答案:

答案 0 :(得分:1)

您谈论的是接收缓冲区大小,就像mq_receive()报告错误一样,但正如您所看到的,您的缓冲区足够长,可以接收任何可以排队到队列中的消息,而且,您似乎根本不要期待收到的消息。

虽然我不确定您是如何以这种方式感到困惑的,但我倾向于认为发送消息时会出现问题:

char accountNumber[15];

...

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

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