我可以使用select来组合stdin和accept吗? [英] Can I use select to combine stdin and accept?

查看:186
本文介绍了我可以使用select来组合stdin和accept吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在C ++ / Linux中实现一个服务器,它经常从终端接收用户输入。最初,我实现了两个单独的线程来处理这种行为。但我意识到,如果用户想关闭服务器,我需要像pthread_cancel这样的服务器线程来取消服务器线程。



然后我决定,在同一个线程中处理两个动作,所以我不必担心资源泄漏。所以我现在是一个选择调用选择stdin fd以及我接受fd。我的代码看起来像这样...

  fdset readfds; 
FD_SET(acceptfd,& readfds);
FD_SET(stdinfd,& readfds);
while(1){
select(n,& readfds,NULL,NULL,NULL);
....
}

由于某种原因,从stdin读取输入。这工作正常,当我从我的fd集合中删除两个fds中的任一个,另一个ω执行预期。但是当我把它们都留在,而acceptfd仍然接受传入的连接,stdinfd未能响应终端输入。



有人知道我可能在这里做错了?这种方法本身有缺陷吗?



感谢您阅读!


c> select 是一个旧的,即将过时的系统调用,您应该优先使用 poll(2) 。如果你仍然使用 select(2)系统调用,你应该先用<$ c $清除 readfds c> FD_ZERO 。并且 FD_SET 宏应该在while循环中,因为 select 允许修改 readfds



poll syscall优于 select因为选择对进程可以有的文件描述符数量(通常为1024,而内核今天能够处理具有更大数量的fds,例如65536)。换句话说, select 要求每个fd都是< 1024(今天为假)。 poll 能够处理任何fd的任何集合。 poll 的第一个参数是一个数组(你可以 calloc 如果你想),它的大小是数字fds要复用。在你的case,它是两个(stdin和第二次听fd),所以你可以使它成为一个局部变量。确保在每次调用 poll 之前清除并初始化它。



您可以使用调试器c $ c> gdb 或只使用 strace


I am trying to implement a server in C++/Linux that regularly takes user input from the terminal. Initially I had implemented two separate threads to handle this behavior. But I realized that I would need something like pthread_cancel to cancel the server thread in case the user wanted to shut down the server.

I then decided that it might be better to handle both actions in the same thread, so I dont have to worry about resource leakage. So what I have now is a 'select' call that selects over the stdin fd as well as my accepting fd. My code looks something like this...

fdset readfds;
FD_SET(acceptfd, &readfds);
FD_SET(stdinfd, &readfds);
while(1) {
  select(n, &readfds, NULL, NULL, NULL);
  ....
}

For some reason I am no longer able to read input from stdin. This works fine when I remove either one of the two fds from my fd set, the other ome performs as expected. But when I leave them both in, while the acceptfd still accepts incoming connections, the stdinfd fails to respond to terminal input.

Does anyone know what I might be doing wrong here? Is this approach inherently flawed? Should I be focusing on keeping the two actions as separate threads and figuring out a way to exit cleanly instead?

Thanks for reading!!

解决方案

As Ambroz commented, multiplexing stdin and some listened fd is possible.

But select is an old, nearly obsolete syscall, you should prefer using poll(2). If you insist on still using select(2) syscall, you should clear the readfds at first with FD_ZERO inside the loop. And the FD_SET macros should be inside the while loop, because select is permitted to modify the readfds.

The poll syscall is preferable to select because select impose a wired-in limit to the number of file descriptors the process can have (typically 1024, while the kernel is today able to deal with a bigger number of fds, eg 65536). In other words, select requires that every fd is < 1024 (which is false today). poll is able to deal with any set of any fd. The first argument to poll is an array (which you could calloc if you wanted to) whose size is the number of fds you want to multiplex. In your case, it is two (stdin and the second listened fd), so you can make it a local variable. Be sure to clear and initialize it before every call to poll.

You could debug with a debugger like gdb or just use strace

这篇关于我可以使用select来组合stdin和accept吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆