In linux, how does one generate an event to break out a select / poll / epoll loop on thread termination? Processes have a pidfd and SIGCHILD. Is there something similar for threads?
Edit: this is to directly monitor the thread termination event.
Well the most obvious solution, that comes to mind, is that one of the file descriptors being polled/selected for would be a very special file descriptor, that's reserved for that particular purpose. When you want to "break out" of the select/poll/epoll you simply need to make the appropriate arrangements for this, very special, file descriptor to become available for reading, and this will make it happen.
After select/poll/epoll returns you'll check that file descriptor, just like you would check any other one, and proceed according to whatever should happen in that event. So the only remaining part of this question is what kind of a very special file descriptor would this be?
Well, since you tagged your question with linux, you have many Linux-specific options to choose from.
You can turn off native signal handling in your process, and create a signal file descriptor. Then a sent signal to the process translates to the signal file descriptor becoming available for reading, and reading from it, as documented in the manual page, tells you that the signal has been received.
An event file descriptor could be another option, this one's more suitable for different threads in the same process notifying each other.
Both event and signal file descriptors are eminently pollable/selectable. And there's always the old-school approach of creating a pipe(), selecting/polling the read end of the pipe, and writing to the write end of the pipe to effect the notification.
Related
To my knowledge, the select() function in C can only wait for file descriptors to become active (i.e. for reading them to not block.)
This is useful for a command-line messaging application since everything will be either a socket file descriptor, or stdin.
However, what if I want to incorporate this with a GUI application (for example, one written in Gtk?)
I assume there's no way to tell select() to wait for a button to be pressed, right? So will I have to use multithreading?
If you want to incorporate non-fd activity into a select-based event loop (or other fd-related alternatives like epoll), you can do that by using a pipe. The action triggered by the event (such as a button press) writes a description of the event into the pipe, and the select mask includes the read end of the pipe, so it will be notified of the data availability.
If the events and the handlers are in the same process, it's not necessary to fully serialise the event description, since some other mechanism could be used (a in-memory queue of events, or some such). However, since most events can be easily and efficiently described in a few bytes, serialising the event provides an easily scalable architecture.
In C++ on Linux, from what I understand, if the same signal is delivered multiple times, it's possible that the signal handler will be called only once. Is it possible to override this behavior? Say, for example, that I have several file descriptors, and I want to be notified by a SIGIO whenever there are events on these file descriptors. So I call fcntl with the command F_SETOWN_EX on each of them. But if there are simultaneous events on 2 file descriptors I might get only one SIGIO and then never know that an event occoured on the other file descriptor.
Now I know you might wonder why I want to use signals at all, rather than jusgt epoll or something. The thing is I'm interested in the exact time that the events happen, so I was thinking of calling clock_gettime from the SIGIO signal handler to record the exact time of the event.
Old question, but in case anyone still wonders: you should be able to accomplish what you want by using fcntl with F_SETSIG to select a real-time signal (a signal number >= SIGRTMIN), instead of using the default SIGIO.
I'm doing some research on the Linux kernel, particularly the input subsystem. I'm interested in reading /dev/input/eventX device(s) for different input events (mainly keyboard and mouse).
However the read() operation blocks. The only thing I can think of is creating a state of all the keyboard keys and mouse buttons, and then create a new thread for reading keyboard and mouse states (those threads might be blocked from time to time), and from my main process, access the state of the keyboard and mouse.
However, I'm not very experienced in non blocking programming under C++ and Linux and I think that a thread for each device might be an overkill.
I'd like to know if there are other ways to handle input in non blocking way, or using threads is fine?
Thanks, skwee.
You can check out the poll system call for this. Is for handling I/O on multiple file descriptors. One possibility would be to spawn only one thread to poll for events on multiple file descriptors.
Here is some reading material : http://www.makelinux.net/ldd3/chp-6-sect-3
You can set the file description to non blocking. You can also use select/poll to check to see if data is available to be read in which case you don't need non blocking. See this thread;
Non-blocking call for reading descriptor
I have a problem with my multithreaded networking server program.
I have a main thread that is listening for new client connections. I use Linux epoll to get I/O event notifications. For each incoming event, I create a thread that accept() the new connection and assign a fd to it. Under heavy loading, it can occur that the same fd is assigned twice causing my program to crash.
My question is: how can the system re-assign a fd that is still used by another thread?
Thanks,
Presumably there is a race condition here - but without seeing your code it's hard to diagnose.
You would be better to accept on the Main thread and then pass the accepted socket to the new thread.
If you pass your listening socket to a new thread to then perform the accept - you're going to hit a race condition.
For further information you can look here: https://stackoverflow.com/a/4687952/516138
And this is a good background on networking efficiency (although perhaps a bit out of date).
You should call accept() on the same thread that you are calling epoll() on. Otherwise you are inviting race conditions.
File descriptors are modified in a "per process basis". This means that they are unique for each process. This means that multiple threads can share the same file descriptors in the same process.
Having an accept syscall returning the same file descriptor inside the same process is a very strong indication that some of your threads are closing the previous "version" of the repeated file descriptor.
Issues like this one may be difficult to debug in complex software. A way to identify that in Linux system is to use the strace command. One can run strace -f -e trace=close,accept4,accept,pipe,open <your program>. That's going to output on your screen the respective syscalls specified in the command along with which thread is calling it.
I have a C++ console app that uses open() [O_RDWR | O_NONBLOCK], write(), select(), read() and close() to work with device file. Also ioctl() can be called to cancel current operation. At any given time only one user can work with device.
I need to come up with C++ class having libsigc++ signals that get fired when data is available from device.
The problem: when calling select() application becomes unresponsive as it waits for the data. How to make it responsive - by calling select() in worker thread? If so - how will worker thread communicate with main thread? Maybe I should look into boost::asio?
How to make it responsive - by calling select() in worker thread
you can use dup(), this will duplicated your file descriptors... thus you can move entire read operations into another thread. thus your write thread and processing thread will be responsive, even when the read [select()] thread is in sleeping.
signal emitting overhead of libsigc++ is minimal, thus i think you can embedded code inside the read thread itself. slots can exist in different thread, this is where you will receive your signals...
I think Thrift source code [entirely boost based] might be of your interest, though thrift does not use libsigc++.
It sounds as though you've misunderstood select; the purpose of select (or poll, epoll, etc) is not "wait for data" but "wait for one or more events to occur on a series of file descriptors or a timer, or a signal to be raised".
What "responsiveness" is going missing while you're in your select call? You said it's a console app so you're not talking about a GUI loop, so presumably it is IO related? If so, then you need to refactor your select so that waiting for the data you're talking about is one element; that is, if you're using select, build FD_SETs of ALL file/socket descriptors (and stdin and stdout are file descriptors) that you want to wait on input for.
Or build a loop that periodically calls "select" with a short timeout to /test/ for any pending input and only try and read it when select tells you there is something to read.
It sounds like you have a producer-consumer style problem. There are various way to implement a solution to this problem, but most folks these days tend to use condition variable based approaches (see this C++11 based example).
There are also a number of design patterns that when implemented can help alleviate your concurrency problem, such as:
Half-Sync / Half-Async
A producer-consumer style pattern that introduces a queue between an asynchronous layer that fills the queue with events, and a synchronous layer that processes those events.
Leader / Followers
Multiple threads take turns handling events
A related discussion is available here.