gpt4 book ai didi

c - Cygwin 中的 mq_notify 不会触发

转载 作者:太空狗 更新时间:2023-10-29 15:41:06 28 4
gpt4 key购买 nike

我正在使用 POSIX 队列 (mqueue) 在线程之间进行通信。

我遇到的问题是 mq_notify 在我的 Cygwin 单元测试中没有按预期运行。它永远不会触发,即使消息队列从空变为 1 条消息。

我做了一个在 Linux 上运行的例子。当在 Cygwin 中编译相同的代码时,它不起作用。

会不会是Cygwin不支持mq_notify还是Cygwin的bug?

通知示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "mqueue.h"

static void error(const char *msg)
{
perror(msg);
exit(1);
}

static void handleMessage(union sigval sv)
{
ssize_t n;
char buf[256];
struct mq_attr mqAttr = {0};
mqd_t mqdes = *((mqd_t *) sv.sival_ptr);

printf("handleMessage\n");
if (mq_getattr(mqdes, &mqAttr) == -1) {
error("mq_getattr");
}

printf("handleMessage msgs:%i\n", mqAttr.mq_curmsgs);

while (mqAttr.mq_curmsgs > 0) {
n = mq_receive(mqdes, buf, mqAttr.mq_msgsize, NULL);

if (n == -1) {
error("mq_receive");
break;

} else {
printf("Read %ld bytes from MQ\n", (long) n);
}

if (mq_getattr(mqdes, &mqAttr) == -1) {
error("mq_getattr");
}
}

{
struct sigevent sev;
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = handleMessage;
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = &mqdes;

if (mq_notify(mqdes, &sev) == -1) {
error("mq_notify");
}
}
}

int main(int argc, char *argv[])
{
struct mq_attr mqAttr;
mqd_t queue;
struct sigevent sev;

mqAttr.mq_maxmsg = 10;
mqAttr.mq_msgsize = 50;
mqAttr.mq_flags = 0;

queue = mq_open(argv[1], O_CREAT | O_RDWR, 0666, NULL);

if(queue == -1) {
error("mq_open");
}
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = handleMessage;
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = &queue;

if (mq_notify(queue, &sev) == -1) {
error("mq_notify");
}

while(1) {
/* Pass data to mq */
char buffer[20];
static int cnt = 0;

sprintf(buffer, "mq_send %i", ++cnt);
printf("%s q:%X\n", buffer, queue);
if (mq_send(queue, (char*)buffer, (strlen(buffer) + 1), 100) != 0) {
error("mq_send");
}
usleep(1000000); // sleep 1s
}

return 0;
}

最佳答案

我没有设置 Cygwin,所以无法确认您看到的内容。但是,此错误会跳出:在 handleMessage() 中,您重置通知并使用此行:

sev.sigev_value.sival_ptr = &mqdes;

这是行不通的,因为 mqdes 是当前堆栈上的一个变量。一旦队列为空,该线程(及其关联的堆栈)就会消失。当发生这种情况时,当下一个线程启动时,mqdes 可以指向内存中的任何内容。一个简单的解决方法是只使用传递给当前线程的指针。

sev.sigev_value.sival_ptr = sv.sival_ptr;

关于您的主要问题,您确定在程序中进行后续运行之前删除队列吗?如果队列不为空,则永远不会启动新线程。

关于c - Cygwin 中的 mq_notify 不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13362918/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com