2012-12-10 121 views
2

在我的应用程序中,当报警触发时,我从信号处理程序向管道写入一个整数。 在我的主要应用程序中,我永远循环选择()与0超时值。 问题在于信号处理程序成功写入到管道的写入端,但是选择从不显示管道读取端的可读性。因此,在下面的伪代码中,select中的返回值应该为0. 即使更复杂的是,如果我删除select并简单地执行阻塞read(),它就会工作!我可以读取处理程序写入的整数。这仅仅是选择一直认为,管道的读端无法读取,因此始终返回0选择无法正常工作

所以pseduo代码看起来像

int x=0; 
for(;;) 
{ 

    x = select(maxfd, &readfd, NULL, NULL, &dontWait); // dontWait is timeval with tv_sec and tv_usec = 0 
    if (x == 1) 
    //check for read descriptor and do something 
} 
+2

我从未想过我会去用这个当有人居然说'select'被打破:选择不破( http://www.codinghorror.com/blog/2008/03/the-first-rule-of-programming-its-always-your-fault.html) –

+0

@BrianRoach它更像是一个英语问题。在解决了这个问题几个小时之后,到了晚上,我真的没有想到比我的选择无法工作的更好的标题。我真正的意思是我的选择在我的上下文中的使用,当然不是那个选择被打破了 – Jimm

+0

对不起,它意味着比其他任何事情更开玩笑/开玩笑。我的意思是没有进攻。 –

回答

6

select功能修改两个集和超时。在调用select之前,您必须重新初始化描述符集并超时循环的每次迭代。

此外,你不应该使用if (x == 1),但使用if (FD_ISSET(some_fd, &readfd))。并且请记住maxfd应该是任何集合中使用的最大文件描述符加上一个

+0

谢谢,通过重新初始化描述符集,问题解决了!重新初始化描述符集的基本原理是什么? – Jimm

+1

@Jimm'select'函数修改它的参数。 –

+0

谢谢,好教训。 – Jimm

1

select适用于fd_set s。看起来你正试图传递一个指向描述符(一个int)的指针来选择?

我建议您咨询该手册页selectfd_set

http://linux.die.net/man/3/fd_set