I'm designing a C program in linux where I'll have two threads. One main thread is the event_processor_thread which does the main function processing. Second thread is an event_dispatcher thread running always in the background, writing to and reading from multiple interfaces in real time (non blocking async i/o)
I did some research on the net, and found that the best ways to implement non-blocking socket i/o can be accomplished via
select()
I chose the latter, as its easier, and i'll have at the most 4 interfaces to read from/write to.
I'm clear on the listen/read mechanisms using readfds
, but I'm unsure on how to use the writefds
! If I put my data from the event_processor_thread to a shared memory and have this event dispatcher thread read this from shared memory and write using send()
, Will select take care of sending the data to socket on its own ? Is this why I need to use writefds
in select()
?
My apologies if my questions is not clear, what I basically want is to have a non blocking i/o thread to dispatch events to/from the event processor thread to the external interface. Any inputs in this regard is highly appreciated. Thanks!
select() allows a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible).
RETURN VALUE On successful completion, select() returns the total number of bits set in the bit masks. Otherwise, -1 is returned, and errno is set to indicate the error.
You can use the select() call to pass a bit set containing the socket descriptors for the sockets you want checked. The bit set is fixed in size using one bit for every possible socket. Use the nfds parameter to force select() to check only a subset of the allocated socket bit set.
select() uses a timeout that is a struct timeval (with seconds and microseconds), while pselect() uses a struct timespec (with seconds and nanoseconds). select() may update the timeout argument to indicate how much time was left. pselect() does not change this argument.
The writefds of select is to check that the file descriptor is ready for writing. For a socket that means that the send buffer associated with the socket is not full.
Let's assume that the sockets on your platform have an 8 kb buffer and you want to send 100 kb of data.
You call write
and get a return value of 8192 indicating that the first 8192 bytes have been written. The next call to write returns either EAGAIN
or EWOULDBLOCK
indicating that the send buffer is full.
You can now use select
to find out when there is room in send buffer again (that is, when one tcp/ip packet has been transferred to the client) so that you can continue writing. At the same time you can be listening for new connections and waiting for input from clients.
Note that select
never sends any data, it just monitors the status of several file descriptors at once.
No, select()
will not "take care of writing". It will notify you when one or more of the file descriptors included in the writefds set becomes writable. This can mean that the fd(s) in question have finished the previous (non-blocking) write you did, so that you can now do another.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With