我有一些使用POSIX消息队列的进程,当错误处理我希望所有进程都关闭时。麻烦的是,有时它们没有自己完成,并且当队列已满时在mq_send上被阻塞(或者当它为空时在mq_receive上被阻塞)。在彻底阅读文档后,我注意到有一种方法可以阻止阻塞,即用O_NONBLOCK
设置mq_setattr()
标志。虽然大多数情况下接收错误的过程应该足够快,并设置标志以便进程永远不会挂起来等待它,但是不能确定是这种情况。所以我想知道当属性设置为非阻塞时,已经等待的进程是否会被唤醒,并且我编写了以下程序来验证它没有。该计划是否正确?除了手动调用mq_receive()
以便在mq_maxmsg == mq_curmsgs
或向他们发送信号时人为降低消息数量时,可以采取其他措施吗?
#include <stdio.h>
#include <mqueue.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
void system_err (char* fmt, ...) {
va_list fmt_args;
fprintf(stderr, "ERROR: ");
va_start(fmt_args, fmt);
vfprintf(stderr, fmt, fmt_args);
va_end (fmt_args);
fprintf(stderr," (%d; %s)\n", errno, strerror(errno));
exit(1);
}
int main() {
struct mq_attr a;
a.mq_flags = O_NONBLOCK;
char bfr[819300];
unsigned int prio = 69;
int x;
switch (fork()) {
case -1:
system_err("oops");
break;
case 0:
sleep(1);
x = mq_open("/lol", O_RDWR);
if (x == -1) {
system_err("childoops");
return -1;
}
x = mq_receive(x, bfr, sizeof(bfr), &prio);
if (x == -1) {
system_err("receiveoops");
return -1;
}
printf("childfin: %d %s %d\n", x, bfr, prio);
break;
default:
x = mq_open("/lol", O_CREAT | O_RDWR, 0755, NULL);
if (x == -1) {
system_err("parentoops");
return -1;
}
mq_getattr(x, &a);
printf("flag:%ld\n\n", a.mq_flags);
a.mq_flags = O_NONBLOCK;
sleep(5);
if (mq_setattr(x, &a, NULL)) {
system_err("setattr");
}
mq_getattr(x, &a);
printf("flag:%ld\n\n", a.mq_flags);
printf("parentwait");
fflush(stdout);
wait(0);
printf("parentfin");
}
return 0;
}