I am developing a Windows application that has a separate thread for processing user (or 3rd party) application input via stdin.
This thread is designed such that it waits via WaitForMultipleObjects on two events:
A death signal. When this signal is raised, the interface-processing thread shuts down.
An interface signal. When this signal is raised, there is input ready to be read. The input is read and processed.
Under Windows this thread enters a main loop where it Waits for these 2 events (where bWaitAll is FALSE). Waiting on the stdin handle has the effect of signaling when there is input ready to be read, and the other event is set from elsewhere in the application.
This works exactly as I want. It waits for an event to be raised without entering in to a busy-wait, and it waits for both event simutaneously.
I wish to port this functionality to Linux, but I'm not sure how to achieve the desired result. Fundamentally, what I really want is this:
Under Linux, how do I design a thread so that it will respond
immediately to user-input on stdin, yet it can also respond
immediately to a kill-flag being raised from elsewhere in the
application?
In order to accomplish the latter, it seems to me that I cannot use cin, gets, getch or any other function that blocks until the user has entered text. Yet I do not know how to read user input in a console-based application without blocking.
I'm open to any change in architecture (if there's a more Linux-y way to do this) that include having user input processed in a separate thread that can be terminated from elsewhere in the application. I'm using GCC 4.4, and Boost 1.51.
The standard way of doing this in Linux is to use the select(2) system call. However, select is more limited than WaitForMultipleObjects, in that it can only wait on file descriptors, not other kinds of objects (such as events). So, the typical way of working around that is to create a pipe and write a dummy value to the pipe as your "signal".
Something like this:
// Error checking omitted for expository purposes
int pipefd[2];
pipe(pipefd); // Create the pipe
while(1)
{
// Create file descriptor set of stdin and the read end of the pipe
fd_set fds;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
FD_SET(pipefd[0], &fds);
int maxfd = MAX(STDIN_FILENO, pipefd[0]);
// Wait until input becomes available on either stdin or the pipe
int num_available = select(&fds, NULL, NULL, NULL);
// Read & process stdin if possible (will not block)
if (FD_ISSET(STDIN_FILENO, &fds))
{
int n = read(STDIN_FILENO, buffer, size);
...
}
// Read & process pipe if possible (will not block)
if (FD_ISSET(pipefd[0], &fds))
{
char dummy;
read(pipefd[0], &dummy, 1);
// Handle signal (e.g. break out of loop)
}
}
Then to signal to the thread that it's done, just write a single byte to the write end of the pipe:
char dummy = 42;
write(pipefd[1], &dummy, 1);
libev (and several similar incarnations) offers a convenient abstraction around select including being able to pend on signals.
If you have the option to alter the origin of "An interface signal" then you could consider changing it to use raise instead.
Related
This code, which I have no control over, reads a file using overlapped I/O:
// Read file asynchronously
HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...);
BYTE buffer[10];
OVERLAPPED oRead = { 0 };
ReadFile(hFile, buffer, 10, NULL, &oRead);
// Do work while file is being read
...
// Wait for read to finish
WaitForSingleObject(hFile, INFINITE);
// ReadFile has finished
// buffer now contains data which can be used
...
In another thread (actually in an API hook of ReadFile), I need to signal the hFile to unblock the WaitForSingleObject. Normally Windows (or the device driver handling the ReadFile) does this, but I need to simulate it.
None of the APIs I found that normally do this work with hFile, including ReleaseMutex, ReleaseSemaphore, and SetEvent. They all return Error 6 (handle is invalid). Is there an API that works with a file, named pipe, or communications device?
I know it is not recommended to WaitForSingleObject(hFile), but the above code is a given, and I need to work with it. Thanks!
So far as I know, signaling the file handle takes place internally to Windows, and there is no API even when running in kernel mode. (I believe the file system driver simply tells Windows that the operation is complete and lets Windows figure out how to notify the user-mode process. I may be wrong.)
One resolution would be to issue a genuine ReadFile (a zero-byte read might be sufficient) against the handle in order to signal it.
But it would probably be more sensible to hook WaitForSingleObject, check whether it is being called on the file handle in question, and if so modify the behaviour as appropriate.
My application checks for user input in its main thread:
while (running)
{
std::string console;
if (std::getline(std::cin, console))
{
process(&console);
}
}
Before that I have setup a sigaction to detect CTRL+C in conjunction with a function handler to shutdown other threads.
Now, when a SIGINT occurs the application crashes; GDB output:
I was looking around and found other solutions such as non-blocking input reading: (pseudo-code)
while (running)
{
if (input_avail())
{
getinput
process
}
else
sleep(1);
}
But even that fails for me at the sleep function (nanosleep):
So I'm quite curious on how other people achieve this?
(Using g++ v4.8.2 Kernel 3.10)
Additional info requested:
Before the main thread loop:
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = signalinfo;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGTERM, &sigIntHandler, NULL);
sigaction(SIGQUIT, &sigIntHandler, NULL);
sigaction(SIGINT, &sigIntHandler, NULL);
Signal handler:
void signalinfo(int signum)
{
// Only setting a flag so threads know to exit.
pCore->Termination(signum);
}
Not sure if it answers your question, but the documentation of the XBoard protocol explains some common strategies how engine engine handle reading from stdin.
It basically sketches how you might implement your non-blocking pseudo code.
Source: XBoard protocol (6. Hints on input/output)
... on the input side, you are likely to want to poll during your search and stop it if new input has come in. If you implement pondering, you'll need this so that pondering stops when the user makes a move. You should also poll during normal thinking on your move, so that you can implement the "?" (move now) command, and so that you can respond promptly to a "result", "force", or "quit" command if xboard wants to end the game or terminate your engine. Buffered input makes polling more complicated -- when you poll, you must stop your search if there are either characters in the buffer or characters available from the underlying file descriptor.
The most direct way to fix this problem is to use unbuffered operating system calls to read (and poll) the underlying file descriptor directly. On Unix, use read(0, ...) to read from standard input, and use select() to poll it. See the man pages read(2) and select(2). (Don't follow the example of GNU Chess 4 and use the FIONREAD ioctl to poll for input. It is not very portable; that is, it does not exist on all versions of Unix, and is broken on some that do have it.) On Win32, you can use either the Unix-like _read(0, ...) or the native Win32 ReadFile() to read. Unfortunately, under Win32, the function to use for polling is different depending on whether the input device is a pipe, a console, or something else. (More Microsoft brain damage here -- did they never hear of device independence?) For pipes, you can use PeekNamedPipe to poll (even when the pipe is unnamed). For consoles, you can use GetNumberOfConsoleInputEvents. For sockets only, you can use select(). It might be possible to use WaitForSingleObject more generally, but I have not tried it. Some code to do these things can be found in Crafty's utility.c, but I don't guarantee that it's all correct or optimal.
A second way to fix the problem might be to ask your I/O library not to buffer on input. It should then be safe to poll the underlying file descriptor as described above. With C, you can try calling setbuf(stdin, NULL). However, I have never tried this. Also, there could be problems if you use scanf(), at least with certain patterns, because scanf() sometimes needs to read one extra character and "push it back" into the buffer; hence, there is a one-character pushback buffer even if you asked for stdio to be unbuffered. With C++, you can try cin.rdbuf()->setbuf(NULL, 0), but again, I have never tried this.
A third way to fix the problem is to check whether there are characters in the buffer whenever you poll. C I/O libraries generally do not provide any portable way to do this. Under C++, you can use cin.rdbuf()->in_avail(). This method has been reported to work with EXchess. Remember that if there are no characters in the buffer, you still have to poll the underlying file descriptor too, using the method described above.
A fourth way to fix the problem is to use a separate thread to read from stdin. This way works well if you are familiar with thread programming. This thread can be blocked waiting for input to come in at all times, while the main thread of your engine does its thinking. When input arrives, you have the thread put the input into a buffer and set a flag in a global variable. Your search routine then periodically tests the global variable to see if there is input to process, and stops if there is. WinBoard and my Win32 ports of ICC timestamp and FICS timeseal use threads to handle multiple input sources.
The WaitNamedPipe function allows a pipe client application to synchronously wait for an available connection on a named pipe server. You then call CreateFile to open the pipe as a client. Pseudocode:
// loop works around race condition with WaitNamedPipe and CreateFile
HANDLE hPipe;
while (true) {
if (WaitNamedPipe says connection is ready) {
hPipe = CreateFile(...);
if (hPipe ok or last error is NOT pipe busy) {
break; // hPipe is valid or last error is set
}
} else {
break; // WaitNamedPipe failed
}
}
The problem is that these are all blocking, synchronous calls. What is a good way to do this asynchronously? I can't seem to find an API that uses overlapped I/O to do this, for example. For example, for pipe servers the ConnectNamedPipe function provides an lpOverlapped parameters allowing for a server to asynchronously wait for a client. The pipe server can then call WaitForMultipleObjects and wait for the I/O operation to complete, or any other event to be signaled (for example, an event signaling the thread to cancel pending I/O and terminate).
The only way I can think of is to call WaitNamedPipe in a loop with a short, finite timeout and check other signals if it times out. Alternatively, in a loop call CreateFile, check other signals, and then call Sleep with a short delay (or WaitNamedPipe). For example:
HANDLE hPipe;
while (true) {
hPipe = CreateFile(...);
if (hPipe not valid and pipe is busy) {
// sleep 100 milliseconds; alternatively, call WaitNamedPipe with timeout
Sleep(100);
// TODO: check other signals here to see if we should abort I/O
} else
break;
}
But this method stinks to high heaven in my opinion. If a pipe isn't available for awhile, the thread continues to run - sucking up CPU, using power, requiring memory pages to remain in RAM, etc. In my mind, a thread that relies on Sleep or short timeouts does not perform well and is a sign of sloppy multi-threaded programming.
But what's the alternative in this case?
WaitNamedPipe is completely useless, and will just use all the cpu if you specify a timeout and there's no server waiting for it.
Just call CreateFile over and over with a Sleep like you're doing, and move it to other threads as you see appropriate. There is no API alternative.
The only "benefit" WaitNamedPipe provides is if you want to know if you can connect to a named pipe but you explicitly don't want to actually open a connection. It's junk.
If you really want to be thorough, your only options are
Ensure that whatever program is opening the named pipe is always calling CreateNamedPipe again immediately after it's named pipe is connected to.
Have your program actually check if that program is running.
If your intent is really not to have additional connections, still call CreateNamedPipe, and when someone connects, tell them to go away until they're waited a given amount of time, the close the pipe.
Why can't the server just create more pipes? The performance hit in the scenario you describe isn't a problem if it is rare.
I.e. if there are usually enough pipes to go round what does it matter if you use CreateFile/Sleep instead of WaitForMultipleObjects? The performance hit will not matter.
I also have to question the need for overlapped IO in a client. How many servers is it communicating with at a time? If the answer is less than, say, 10 you could reasonably create a thread per connection.
Basically I am saying I think the reason there is no overlapped WaitforNamedPipe is because there is no reasonable use-case which requires it.
You can open the pipe file system at \\.\pipe\ and then use DeviceIoControl to send FSCTL_PIPE_WAIT.
I'm writing a program that reads in a loop from the stdin, using the function fgets, as follows:
while(fgets(buffer2, BUFFERSIZE , stdin) != NULL){
//Some code
}
I want my code to be non-blocking, that is: I don't want the program to hold on the 'fgets' line when there's no input at the moment from the user.
How can i do it?
fgets() is a blocking function, it is meant to wait until data is available.
If you want to perform asynchronous I/O, you can use select(), poll(), or epoll(). And then perform a read from the file descriptor when there is data available.
These functions use the file descriptor of the FILE* handle, retrieved by:
int fd = fileno(f);
If you are using Unix or Linux, then one solution can be to mark the file descriptor used by the file to be non-blocking. Example:
#include <fcntl.h>
FILE *handle = popen("tail -f /als/als_test.txt", "r");
int fd = fileno(handle);
flags = fcntl(fd, F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(fd, F_SETFL, flags);
fgets should be non-blockng now and will return a null and set an error code for you.
If you have a proper POSIX environment, you can use select() or poll() to check for input on stdin's descriptor before calling fgets()... read().
Jan's comment below (thanks!) explains why you can't use fgets() with this approach... summarily, there's an extra layer of buffering in the FILE object, and data can already be waiting in though the select() finds nothing more on the file descriptor... preventing your program from responding in a timely way, and potentially hanging if some other system is waiting for a response to already sent data before sending more on stdin.
You basically have two options:
Run that loop in a separate thread.
Check if your OS supports some API for non-blocking IO.
This would sound a little like overkill, but this is the one, that comes to my mind.
Use 2 different threads - one using this loop and waiting blocking ( I don't think that this could be done non-blocking). And when something is read, push it into a pipe.
Meanwhile, the other thread will do whatever it needs to do and check for data in the pipe from time to time ( apparently, you want this to be asynchronous, or at least I get it this way. If so, this means different threads )
But then, you'll need to synchronize the two threads very well. You should check your OS about multithreading and IO operations.
On Linux, you can specify the end of input by pressing ctrl-d, and of-course you can do this using separate thread.
I'm a noob to linux programming, so please bear with me. In my application, I fork(), then execl() another binary after having setup a single pipe for reading in. After the fork and exec are OK, i do a dup2() for reading in from the stdout of the executed binary. I need my parent application to wait for output from the process it has created and once there is output, read it. I figured I will use select(), and wait for a few milliseconds before trying to see if there is data to be read and if there is, use read(). However my code does not work because select() takes as argument an fd_set, while my pipe is of int converted by pipe() and dup2(). What can I do to overcome this and is there another alternative? Note, I'm not blocking the parent process until the process ends, but want to read info while the child process runs.
To use select() you must create a struct fd_set and populate it using the FD_ macros. In this way you will inform the function which descriptors you are interested in (note that it is common to be interested in several at once). For example:
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(your_input_fd, &rfds);
int retval = select(your_input_fd + 1, &rfds, NULL, NULL, NULL);
The first argument to select is to be the highest-numbered file descriptor you are interested in, plus one. That, along with example code, is explained here:
http://linux.die.net/man/3/fd_set