mq_notify 不通知事件(Linux 编程)
我正在使用 mq_notify
来获取有关消息队列上的事件的通知,但我注册的通知程序函数没有被调用。我错过了什么吗?
我将我的代码片段粘贴在下面:
static void sigNotifier(union sigval sv)
{
printf ("I'm called.\n");
}
int main()
{
mqd_t queueID = 0;
message_t msg;
int retval;
struct mq_attr attr;
struct sigevent sev;
attr.mq_msgsize = MSG_SIZE;
attr.mq_maxmsg = 30;
errno = 0;
queueID = mq_open(MSG_QUEUE_NAME, O_RDONLY, 0666, &attr);
if (queueID == -1) {
printf ("Message queue open failed: %d\n", errno);
}
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = sigNotifier;
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = &queueID;
retval = mq_notify(queueID, &sev);
if (retval < 0) {
printf ("Notification failed: %d\n", errno);
}
while (1);
}
I'm using mq_notify
to be notified about events on a message queue, but my registered notifier function is not being called. Did I miss something?
I'm pasting my code snippet below:
static void sigNotifier(union sigval sv)
{
printf ("I'm called.\n");
}
int main()
{
mqd_t queueID = 0;
message_t msg;
int retval;
struct mq_attr attr;
struct sigevent sev;
attr.mq_msgsize = MSG_SIZE;
attr.mq_maxmsg = 30;
errno = 0;
queueID = mq_open(MSG_QUEUE_NAME, O_RDONLY, 0666, &attr);
if (queueID == -1) {
printf ("Message queue open failed: %d\n", errno);
}
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = sigNotifier;
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = &queueID;
retval = mq_notify(queueID, &sev);
if (retval < 0) {
printf ("Notification failed: %d\n", errno);
}
while (1);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
手册页mq_notify:
1) 仅当新消息到达并且队列先前为空时才会发生消息通知。如果调用 mq_notify() 时队列不为空,则仅在队列清空且新消息到达后才会发生通知。
2)通知发生一次:通知下发后,通知注册被移除,其他进程可以注册消息通知。如果被通知的进程希望接收下一个通知,它可以使用 mq_notify() 来请求进一步的通知。
3) 一个进程只能注册一个来接收来自消息队列的通知。
因此:
1) 在使用 mq_notify() 注册后,立即清空 MsgQ 以在 reader 进程中接收新消息。
2) 重新注册notify函数以接收下一条消息。
3) 仅注册 1 个进程用于从 Q 接收消息。
这是一个简单的 C++ 消息队列读取器代码:
这是一个简单的消息 Q 写入器代码:
Man Page mq_notify:
1) Message notification occurs only when a new message arrives and the queue was previously empty. If the queue was not empty at the time mq_notify() was called, then a notification will occur only after the queue is emptied and a new message arrives.
2) Notification occurs once: after a notification is delivered, the notification registration is removed, and another process can register for message notification. If the notified process wishes to receive the next notification, it can use mq_notify() to request a further notification.
3) Only one process can be registered to receive notification from a message queue.
So:
1) Empty the MsgQ to recv new messages in the reader process immediately after registering with mq_notify().
2) Re-register in the notify function for receiving next message.
3) Register only 1 process for receiving messages from Q.
Here is a simple message queue reader code in C++:
Here is a simple message Q writer code:
因为代码是手册页的副本,所以我会问:
在Linux下,您可以使用select/poll/epoll来等待有关队列的通知以及
mqd_t 是普通文件描述符。
Because the code is copies from man page I would ask:
Under Linux you can use select/poll/epoll to wait for notifications about queue as well as
mqd_t is ordinary file descriptor.
还要检查队列是否已经有消息。如果队列中存在消息,则 mq_notify() 将不会收到通知,直到队列为空,然后有新消息进入。
由于队列在程序运行中是持久的,因此您需要确保在打开之前已在队列上调用 mq_unlink() 。
Also check if the Queue already has messages. If messages exist on the queue then mq_notify() would not get notification untill the queue is empty and then new messages come in.
Since the queue is a persistent across program runs you want to make sure the mq_unlink() is already called on the queue before open.