根据 POSIX 标准,在同一套接字上对 send/recv 的并行调用是否有效?
Are parallel calls to send/recv on the same socket valid as per POSIX standard?
我试图了解套接字 API(recv
、send
、select
、close
等)在并行线程上的用法。这意味着在两个并行线程上使用一个套接字文件描述符。我已经浏览过 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 手册页没有说明任何相关内容。
我还想知道下面列出的并行线程使用场景是否在 POSIX 套接字 API 中有效
1) 在两个并行线程中调用 recv
和 send
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) 在两个并行线程中用 select
调用 recv
和 send
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) 在两个并行线程中用 setsockopt
、ioctl
、fcntl
调用 recv
和 send
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.
正如许多人评论的那样,您可以安全地从不同线程调用上述调用。
案例“1”和“2”对于生产代码来说非常典型(一个线程接收,一个发送,每个线程处理许多与 select()
的连接)。
案例“3”有点奇怪,可能是问题的根源(它会起作用,调用有效,但获得所需的行为可能并不直接)。通常,您要么在开始时将套接字置于非阻塞模式并处理 send()
/recv()
调用中的 EAGAIN/EWOULDBLOCK 错误,要么阻塞并使用 select()
/pselect()
/poll()
/ppoll()
。
这种情况下的发送线程会随机"find"套接字处于阻塞或非阻塞模式:我不会那样做。
我试图了解套接字 API(recv
、send
、select
、close
等)在并行线程上的用法。这意味着在两个并行线程上使用一个套接字文件描述符。我已经浏览过 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 手册页没有说明任何相关内容。
我还想知道下面列出的并行线程使用场景是否在 POSIX 套接字 API 中有效
1) 在两个并行线程中调用 recv
和 send
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) 在两个并行线程中用 select
调用 recv
和 send
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) 在两个并行线程中用 setsockopt
、ioctl
、fcntl
调用 recv
和 send
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.
正如许多人评论的那样,您可以安全地从不同线程调用上述调用。
案例“1”和“2”对于生产代码来说非常典型(一个线程接收,一个发送,每个线程处理许多与 select()
的连接)。
案例“3”有点奇怪,可能是问题的根源(它会起作用,调用有效,但获得所需的行为可能并不直接)。通常,您要么在开始时将套接字置于非阻塞模式并处理 send()
/recv()
调用中的 EAGAIN/EWOULDBLOCK 错误,要么阻塞并使用 select()
/pselect()
/poll()
/ppoll()
。
这种情况下的发送线程会随机"find"套接字处于阻塞或非阻塞模式:我不会那样做。