我正在使用消息队列进行第一次练习。我希望mq_receive阻止,所以我没有打开O_NOBLOCK。
mq_receive方法正在返回,而perror()正在打印"消息太长"。这是在我发送信息之前。
ATM发送消息:
void* run_ATM(void* arg) {
int status;
char accountNumber[15];
cout << "ATM is running" << endl;
cout << "Please input an account number > ";
cin >> accountNumber;
status = mq_send(PIN_MSG, accountNumber, sizeof(accountNumber), 1);
}
数据库接收它们
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, 100, NULL);
if (status < 0){
perror("error ");
} else {
cout << "received account number\t" << received_acct_number << endl;
}
}
}
这只是初步代码 - 所以它最终会做更多。我只是想得到一个基本的工作示例。
编辑:运行此代码所需的其他代码:
#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, DB_MSG;
int main(int argc, char const *argv[])
{
pthread_attr_t attr;
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);
DB_MSG = mq_open(DB_MSG_NAME, O_CREAT | O_RDWR, 0666, &mq_attribute);
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);
}
接收缓冲区大于消息队列大小,所以应该没有问题,对吧?
答案 0 :(得分:2)
如果您检查了函数的错误返回并打印出来,则错误很明显。您正在将textarea
和accountNumber
的值转换为指针而不是转换其地址。你想要:
PIN
请注意,我们的代码仍然存在很多问题,最明显的是您因未正确处理其大小而超出这些变量。您可以像这样修复:
status = mq_send(PIN_MSG, (const char*) &accountNumber, MESSAGE_QUEUE_SIZE, 1);
status = mq_send(PIN_MSG, (const char*) &PIN, MESSAGE_QUEUE_SIZE, 1);
status = mq_receive(PIN_MSG, (char*) &received_acct_number, 100, NULL);
status = mq_receive(PIN_MSG, (char*) &received_PIN, MESSAGE_QUEUE_SIZE, NULL);
但实际上你应该有某种消息格式,你应该将消息序列化为该格式。
答案 1 :(得分:-1)
所以看起来主要的问题是剩余的消息队列,因为它们没有在代码中正确关闭/取消链接。
我的原始代码中有一些错误,我很欣赏那些指出并给我解决方案的答案。
当尝试更改消息的格式时出现问题,我想再次调用mq_open
时,它不会更改消息大小(因为消息队列已经存在)。这导致代码中的大小错误。重新启动是一种解决方法,但解决方案是使用mq_unlink()
然后mq_close()
正确清理