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