Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use writefds in select ? How to use them in practice?

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

  1. libevent
  2. 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!

like image 419
vinit Avatar asked Nov 19 '13 12:11

vinit


People also ask

What is the purpose of the select mechanism?

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).

What does select() return?

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.

How do you use the select function in socket programming?

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.

How does select timeout work?

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.


2 Answers

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.

like image 178
Klas Lindbäck Avatar answered Oct 17 '22 17:10

Klas Lindbäck


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.

like image 20
unwind Avatar answered Oct 17 '22 15:10

unwind