我试图教自己消息队列,而且我使用互相交谈的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;
}
}
}
我错过了什么吗?为什么会有消息进入,为什么它太大了?
答案 0 :(得分:1)
您谈论的是接收缓冲区大小,就像mq_receive()
报告错误一样,但正如您所看到的,您的缓冲区足够长,可以接收任何可以排队到队列中的消息,而且,您似乎根本不要期待收到的消息。
虽然我不确定您是如何以这种方式感到困惑的,但我倾向于认为发送消息时会出现问题:
char accountNumber[15];
...
status = mq_send(PIN_MSG, accountNumber, sizeof(accountNumber) + 1, 1);
您队列的消息长度限制为15个字节,并且您正在尝试将16字节消息排入队列。而且,您的发送缓冲区实际上首先短于16个字节;如果mq_send()
试图复制16个字节的消息,则会产生未定义的行为。