我有一些捕获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/管道中:
echo "bla" > /tmp/pipe.程序的反应是它从管道读取数据(字符串"bla")并显示其内容--这是可以的。
问题是应用程序一次又一次地调用my SIGIO处理程序。我的意思是“处理程序”proc是无限调用的,所以main() proc中的"while“循环不再运行。
为什么会出现这种效果?我错过什么了吗?我以为每次"echo“调用都只会调用"handler”一次...
发布于 2018-03-26 19:07:42
在echo事件终止后,您在"main“中打开的管道是EOF,因此它会不断地触发SIGIO--command(即管道上的EOF )。因此,您必须在main函数中重新打开管道才能使其再次工作。
但是,在处理程序中重新打开管道没有任何作用。只需在main()中使用open()-call中的fd即可。
发布于 2018-03-27 12:57:17
我想我解决了这个问题。
需要在main()中进行以下更改:
fd = open("/tmp/pipe", O_RDONLY | O_NONBLOCK);当然,处理程序()中的open()也应该删除。现在它可以正常工作了。
https://stackoverflow.com/questions/49488882
复制相似问题