7

I am trying to understand the usage of socket APIs (recv, send, select, close, etc) on parallel threads. That means using one socket file descriptor on two parallel threads. I have gone through this question. But still I am not able to find any standard doc which explains the usage of socket APIs in multiple thread. Even opengroup man page is not telling anything about this.

I also want to know whether below listed parallel thread usage scenarios are valid in POSIX socket APIs

1) Calling recv and send in two parallel threads

int main_thread() {
    fd = do_connect(); //TCP or UDP
    spawn_thread(recv_thread, fd);
    spwan_thread(send_thread, fd);
    ...
}

int recv_thread(fd) {
    while(1) {
        recv(fd, ..)
        ...
    }
}

int send_thread(fd) {
    while(1) {
        send(fd, ..)
        ...
    }
}

2) Calling recv and send with select in two parallel threads

int recv_thread(fd) {
    while(1) {
        select(fd in readfd)
        recv(fd, ..)
        ...
    }
}

int send_thread(fd) {
    while(1) {
        select(fd in write)
        send(fd, ..)
        ...
    }
}

3) Calling recv and send with setsockopt, ioctl, fcntl in two paralle threads

int recv_thread(fd) {
    int flag = 1
    while(1) {
        ioctl(fd, FIONBIO, &flag); //enable non block
        recv(fd, ..)
        flag = 0;
        ioctl(fd, FIONBIO, &flag); //disable non block
        ...
    }
}

int send_thread(fd) {
    while(1) {
        select(fd in write)
        send(fd, ..)
        ...
    }
}
Community
  • 1
  • 1
rashok
  • 12,790
  • 16
  • 88
  • 100
  • How do you plan to use multiple threads? One per connection? A single connection shared between threads? Some other way? – Some programmer dude Mar 30 '16 at 15:18
  • And generally, if the Opengroup reference doesn't explicitly say something is thread-safe, you should consider it unsafe. – Some programmer dude Mar 30 '16 at 15:18
  • yes, single connection shared between two threads. – rashok Mar 30 '16 at 15:29
  • reading and writing on two parallel thread, and calling select also on two parallel thread. In 1st thread calling select with readfd and in another thread calling select with same fd on writefd. – rashok Mar 30 '16 at 16:01
  • 4
    @JoachimPileborg, wrong. It is thread-safe to call send/recv on the same socket from multiple threads (though not neccessarily guranteed to produce meaningful results for stream sockets) - still 100% thread safe. – SergeyA Mar 30 '16 at 16:18
  • @rajaashok: what you describe (reading from the socket in one thread, writing to the same socket in another thread) is perfectly thread-safe. A socket has separate buffers for reading and writing. – Remy Lebeau Mar 30 '16 at 18:49
  • @JoachimPileborg There are no shared buffers in this code. If you're referring to the socket send and receive buffers, they're in the kernel and protected by normal system call atomicity. – user207421 Mar 31 '16 at 08:14

1 Answers1

3

Posix functions are thread-safe "by default":

2.9.1 Thread-Safety

All functions defined by this volume of POSIX.1-2008 shall be thread-safe, except that the following functions need not be thread-safe.

As many have already commented, you can safely call the mentioned calls from different threads.

Case "1" and "2" are quite typical (one thread receiving, one sending, each thread handling many connections with select()) for production code.

Case "3" is somehow odd, and probably source of troubles (it will work, the calls are valid, but it may be not straightforward to get the desired behaviour). Generally you either put the socket in non-blocking mode at the beginning and handle EAGAIN/EWOULDBLOCK errors in send()/recv() calls or blocking and use select()/pselect()/poll()/ppoll().

The sending thread in this case will randomly "find" the socket being in blocking or not-blocking mode: I wouldn't do that.

Sigi
  • 4,826
  • 1
  • 19
  • 23
  • "All functions defined by this volume of POSIX.1-2008 shall be thread-safe" - I think this says non reentrant functions (`localtime`, `gmtime` etc) are not thread safe, as it returns static variable address. But its not saying the APIs in `sys/socket.h` is thread safe even if we call with same fd. – rashok Mar 31 '16 at 09:25
  • 2
    socket functions are notably thread-safe even if called on the same fd. What's true is that it's not recommended to let many threads write/read to/from the same socket because it will lead to unreliable behaviour/unportable code (for example because send()/recv() are not guaranteed to send/recv the amount of data that has been specified - that's why letting one thread to read, one to write is correct), but all the calls not in the list are requested to be thread-safe to the implementers. socket functions included even if on the same fd. – Sigi Mar 31 '16 at 09:42