On my journey to get a Software running under Windows and Linux, I had to rewrite the socket layer. On Windows I changed from select to WSAPoll and use a WSAWaitForMultipleEvents before including a standard event to cancel the operation before timeout when necessary. As I have to handle more than 1024 in and out sockets, I have to change from select to poll on linux to. Is there any way to cancel the wait on poll under linux. I have to add remoe connections, which will be slowed down by the wait timeout by the poll.
Create a pseudo internal event using pipe() and add the read side of this to the poll() list, making it the first event.
When you want to cancel the poll write a character to the pipe and poll() will return. You will know it's an internal event as it will have index 0.
You can even make this a crude messaging system by passing different values down the pipe.
You can do the same this with your Windows code using a manual event.
See this IoEvent class that does just that.
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.
I am searching solution to wake-up select call in c++, As per application requirement i cant set timeout because of multiple thread using select system call.
Please see below scenario.
i want to wakeup select system call waiting on other thread. I tried to write data on the thread from main thread but still it is not able to wakeup it.
I want to close thread and socket if there is empty data on this thread.
It is wakes up select call if socket connection is close from other process, but not working with thread.
Does any one have idea regarding this
On a recent Linux you can use eventfd, on everything in general - a pipe, usage - register one side of the pipe in selector for readability along with actual socket(s), to wake up a selector - just write one byte to the other end of the pipe. Alternatively (if your libc has it) you can use pselect with a sigmask to catch the ALRM signal and raise that signal whenever you need to wake the selector up. Be very careful with using signals approach in a multithreaded application (as "I would not use"), as if not done right a signal may be delivered to a random thread.
Thanks all for valuable suggestion, I am able to resolve the issue with shutdown() call on socket FD using reference answer present on this link, it will pass wakeup signal to select, which is waiting for action. We should close socket only after select call otherwise select will not able to get wake up signal.
I'm studying some codes about RS232 with Borland C++. The implementation of reading data from the port is polling the status of the port by timer. There are some events checking whether the status of the port changed. If the status changed, events trigger the data-reading subroutine.
However, I think that polling is so bad that much resource is spent on the action. Could the program be passive in monitoring the port without any aggressive polling or something else? In other words,
the program hibernates unless some events which triggered by incoming
data in the port activate it.
Is the idea is possible?
Thank you for reading
Best regards
I think for your requirements the design pattern named Reactor is appropriate. Reactor is based on the system call 'select' (which is available in both Unix and Windows environments). From the referenced document,
Blocks awaiting events to occur on a set of Handles. It returns when it is possible to
initiate an operation on a Handle without blocking. A common demultiplexer for I/O
events is select [1], which is an event demultiplexing system call provided by the UNIX
and Win32 OS platforms. The select call indicates which Handles can have operations
invoked on them synchronously without blocking the application process.
You can see that this pattern is encoded as a library in several frameworks such as ACE, Boost.
If you are working with the Win32 API functions for reading the serial port you can call ReadFile. It will suspend until it has the number of bytes you requested or until a timeout that you can set. If your program is a GUI then the serial read should be in a secondary thread so the GUI thread can react to any received Windows messages.
I have a listening thread that waiting for reading on few socket using select and FD_SET. The story is. At some point I will add another socket to the pool and need to abort select and re-initialize FD_SET array fo select. I have an Event to signal pool changes. But how select can react to my Event?
select() at this point of time use timeval with waiting interval of 20 sec and I don't want to changed time to lower value. I don't want frequently re-start select() by timeout...
Is there any way to abort select? What would be the right approach to inform/restart select and force using of new list of socket(at least one socket will be added to pool)
And another question - Msdn says "The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O."
Does that mean that select is not designed to work with sockets that turned to use using async operation?
Use WSAEventSelect() and WSAWaitForMultipleEvents() instead of select(). That way, your pool can create a separate event with WSACreateEvent() and signal it with WSASetEvent() to wake up WSAWaitForMultipleEvents() when needed.
If you want select() to wake up, the easiest way is to send a byte to one of the sockets that select() is waiting on for read access. One way to implement that without affecting functionality of the existing sockets is to create a pair of sockets specifically for that purpose and connect() one to the other.
I'm designing event loop for asynchronous socket IO using epoll/devpoll/kqueue/poll/select (including windows-select).
I have two options of performing, IO operation:
Non-blocking mode, poll on EAGAIN
Set socket to non-blocking mode.
Read/Write to socket.
If operation succeeds, post completion notification to event loop.
If I get EAGAIN, add socket to "select list" and poll socket.
Polling mode: poll and then execute
Add socket to select list and poll it.
Wait for notification that it is readable writable
read/write
Post completion notification to event loop of sucseeds
To me it looks like first would require less system calls when using in normal mode,
especially for writing to socket (buffers are quite big).
Also it looks like that it would be possible to reduce the overhead over number of "select"
executions, especially it is nice when you do not have something that scales well
as epoll/devpoll/kqueue.
Questions:
Are there any advantages of the second approach?
Are there any portability issues with non-blocking operations on sockets/file descriptors over numerous operating systems: Linux, FreeBSD, Solaris, MacOSX, Windows.
Notes: Please do not suggest using existing event-loop/socket-api implementations
I'm not sure there's any cross-platform problem; at the most you would have to use Windows Sockets API, but with the same results.
Otherwise, you seem to be polling in either case (avoiding blocking waits), so both approaches are fine. As long as you don't put yourself in a position to block (ex. read when there's no data, write when buffer's full), it makes no difference at all.
Maybe the first approach is easier to code/understand; so, go with that.
It might be of interest to you to check out the documentation of libev and the c10k problem for interesting ideas/approaches on this topic.
The first design is the Proactor Pattern, the second is the Reactor Pattern
One advantage of the reactor pattern is that you can design your API such that you don't have to allocate read buffers until the data is actually there to be read. This reduces memory usage while you're waiting for I/O.
from my experience with low latency socket apps:
for writes - try to write directly into the socket from writing thread (you need to obtain event loop mutex for that), if write is incomplete subscribe to write readiness with event loop (select/waitformultipleobjects) and write from event loop thread when socket gets writable
for reads - be always "subscribed" for read readiness for all sockets, so you always read from within event loop thread when the socket gets readable