[Rd] Question on non-blocking socket

Simon Urbanek @|mon@urb@nek @end|ng |rom R-project@org
Fri Feb 17 21:55:09 CET 2023


Ben,

yes, by definition - non-blocking means that reads won't block and always return immediately (the point of non-blocking). The loop below is terrible as it will cause 100% CPU usage while it's spinning. It seems that you want to block so why are you using non-blocking mode? select() effectively gets you back to blocking mode, because it does the "block" that read() would normally do in blocking mode. Moreover select() allows you to block for a specified time (the point of the timeout argument) so if you want to wait, you should set the timeout - you should never use a spin loop without timeouts. Also there are many other conditions you should be handling - there may be an error on the socket or EINTR (you should call R's interrupt handler) or EAGAIN (which you do implicitly, but you can't tell it from an actual error).

Sockets and I/O are quite complex matter - it's easy to get it wrong and create hard-to-detect bugs in you code unless you are an expert in it. It's one of the wheels you don't want to be reinventing.

Cheers,
Simon


> On Feb 18, 2023, at 3:00 AM, Ben Engbers <ben.engbers using gmail.com> wrote:
> 
> Hi Tomas,
> 
> Apparently, inserting some kind of socketSelect() is essential when using non-blocking sockets and a client/erve architecture. That is at least one thing that I have learned ;-).
> 
> In C++, between sending and requesting, I inserted a call to this function:
> bool wait(int s) {
>  fd_set read_set;
>  struct timeval timeout {};
>  memset(&timeout, 0, sizeof(timeout));
>  bool done{};
>  while (!done ) {
>    FD_ZERO(&read_set);
>    FD_SET(s, &read_set);
>    int rc = select(s + 1, &read_set, NULL, NULL, &timeout);
>    done = (rc == 1) && FD_ISSET(s, &read_set);
>  };
>  return done;
> };
> 
> Inserting this call was essential in solving my problem.
> 
> Ben
> 
> Op 15-02-2023 om 17:17 schreef Tomas Kalibera:
>> In the example you are waiting only for a single byte. But if the response may be longer, one needs to take into account in the client that not all bytes of the response may be available right away. One would keep receiving the data in a loop, as they become available (e.g. socketSelect() would tell), keep appending them to a buffer, and keep looking for when they are complete.
>> Tomas
>>> Ben
> 
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 



More information about the R-devel mailing list