我正在尝试理解如何使用mqueue.h
在工作线程之间进行通信。我知道mqueue.h
是为进程通信而设计的,而不是线程,但它是我能找到的唯一posix队列API,因为我不能使用外部库。
我写了这段测试代码,但是由于某种原因,接收到的值和发送的值不一样。这段代码的目的是发送一个指针到另一个线程。
#include <stdio.h>
#include <errno.h>
#include <mqueue.h>
#include <pthread.h>
#include <fcntl.h>
typedef struct {
mqd_t id;
char* name;
} thread_data;
struct mq_attr attr = {0, 10, sizeof(char*), 0};
void *new_thread(void *arg) {
char* pArg;
thread_data *pData;
int res;
printf("Waiting to receive message (queue %d)...\n", *(mqd_t*)arg);
fflush(stdout);
res = mq_receive(*(mqd_t*)arg, pArg, sizeof(char*), NULL);
if (res != -1)
{
pData = (thread_data*)pArg;
printf("Message received in %p: %s\n", pData, pData->name);
}
else
{
printf("Failed! errno = %d\n", errno);
}
}
int main(int argc, char *argv[])
{
pthread_t t1;
thread_data data;
data.name = "/thread1";
data.id = mq_open(data.name, O_RDWR | O_CREAT, 0600, &attr);
printf("Sending message %p (size %ld bytes)\n", &data, sizeof(char*));
mq_send(data.id, (char*)&data, sizeof(char*), 0);
printf("Message sent (queue %d).\n", data.id);
pthread_create(&t1, NULL, new_thread, &data.id);
pthread_join(t1, NULL);
return 0;
}
输出如下所示:
$ ./a.out
Sending message 0x7ffd1c63eb20 (size 8 bytes)
Message sent (queue 3).
Waiting to receive message (queue 3)...
Message received in 0x7f5a92279700:
我希望这里有人能解释为什么会发生这种情况,因为我已经花了相当长的时间在这上面。
1条答案
按热度按时间gmxoilav1#
您的代码中没有正确的间接级别,无论是在发送还是接收部分。
您的
mq_send()
调用将发送您试图发送其指针的结构的内容的前8个字节。您的mq_receive()
调用试图将数据存储在未初始化的指针中。要修复发送部分:
注意这里的
&ptr
--您试图发送值ptr
(它本身是一个指针,但在这里并不重要),这意味着您必须将指向该值的指针传递给mq_send
。在receive部分,您必须将其更改为:
同样,你想在这里接收值
pData
,所以你必须传递一个指向该值的指针给mq_receive
,不要直接指定指针,那只意味着访问未初始化的内存。为了更清楚地说明这一点,假设你想发送一个整数,那么你需要下面的代码:
因为你想发送一个指针而不是一个整数,所以改变的是传递给mq函数的变量类型和大小--但是在这两种情况下,你都把
(char*)&variable
传递给mq方法,变量是保存整数还是指针并不重要。