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
selectis an old, nearly obsolete syscall, you should prefer usingpoll(2). If you insist on still usingselect(2)syscall, you should clear thereadfdsat first withFD_ZEROinside the loop. And theFD_SETmacros should be inside the while loop, becauseselectis permitted to modify thereadfds.The
pollsyscall is preferable toselectbecauseselectimpose 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,selectrequires that every fd is < 1024 (which is false today).pollis able to deal with any set of any fd. The first argument topollis an array (which you couldcallocif 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 topoll.You could debug with a debugger like
gdbor just usestrace