我有一些代码,我正在捕捉SIGIO信号。我想写一个应用程序,它将被告知有关到达管道的数据。我故意不想使用select()函数。 这是代码:
void handler (int x)
{
int fd, st;
char buf[32];
printf("signal_entry\n");
fd = open("/tmp/pipe", O_RDWR);
memset(buf, 0, sizeof(buf));
st = read(fd, buf, 32);
printf("st: %d buf: %s\n", st, buf);
close(fd);
printf("signal_exit\n\n");
}
int main (void)
{
int fd, sf, fl, st, num;
struct stat sb;
fd = open("/tmp/pipe", O_RDWR);
memset(&act1, 0, sizeof(act1));
sigfillset(&act1.sa_mask);
act1.sa_handler = handler;
sigaction(SIGIO, &act1, NULL);
sf = fcntl(fd, F_SETOWN, getpid());
fl = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, fl | O_ASYNC);
while (1) {
printf("x\n");
sleep(1);
}
}
运行后每隔1秒显示“x”字母。然后我在管道/ tmp / pipe中写了一些东西:
echo "bla" > /tmp/pipe.
程序的反应是它从管道中读取数据(字符串“bla”)并显示其内容 - 这没关系。
问题是应用程序再次调用我的SIGIO处理程序。我的意思是“handler”proc被无限调用,因此main()proc中的“while”循环不再运行。
为什么会出现这种影响?我错过了什么吗?我认为每个“echo”调用只会调用一次“handler”...
答案 0 :(得分:1)
在echo
- 命令终止后,您打开的管道" main"是EOF,所以它会不断触发SIGIO事件(即管道上的EOF)。
所以你必须在main函数中重新打开管道才能让它再次运行。
然而,在处理程序中重新打开管道没有任何意义。只需使用open()
中的fd - main()
中的来电。
答案 1 :(得分:0)
我想我解决了这个问题。
需要在main()中进行更改:
fd = open("/tmp/pipe", O_RDONLY | O_NONBLOCK);
当然应该删除handler()中的open()。 现在它运作正常。