根据 POSIX 标准,在同一套接字上对 send/recv 的并行调用是否有效?

Are parallel calls to send/recv on the same socket valid as per POSIX standard?

我试图了解套接字 API(recvsendselectclose 等)在并行线程上的用法。这意味着在两个并行线程上使用一个套接字文件描述符。我已经浏览过 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) 在两个并行线程中调用 recvsend

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 调用 recvsend

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) 在两个并行线程中用 setsockoptioctlfcntl 调用 recvsend

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"套接字处于阻塞或非阻塞模式:我不会那样做。