首页 文章

并行调用同一套接字上的send / recv是否符合POSIX标准?

提问于
浏览
3

我试图了解并行线程上套接字API( recvsendselectclose 等)的用法 . 这意味着在两个并行线程上使用一个套接字文件描述符我已经完成了this问题 . 但我仍然无法找到任何解释多线程中套接字API用法的标准文档 . 甚至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, ..)
        ...
    }
}

1 回答

  • 2

    Posix functions are thread-safe "by default"

    2.9.1线程安全本卷POSIX.1-2008定义的所有函数都应是线程安全的,但以下函数不必是线程安全的 .

    正如许多人已经评论过的那样,您可以安全地从不同的线程调用上述调用 .

    Case "1"和"2"非常典型(一个线程接收,一个发送,每个线程处理许多与 select() 的连接)用于 生产环境 代码 .

    Case "3"在某种程度上是奇怪的,可能是麻烦的来源(它会起作用,调用是有效的,但是获得所需的行为可能并不简单) . 通常,您可以在开始时将套接字置于非阻塞模式,并在 send() / recv() 调用或阻塞中处理EAGAIN / EWOULDBLOCK错误并使用 select() / pselect() / poll() / ppoll() .

    在这种情况下,发送线程将随机“查找”处于阻塞或非阻塞模式的套接字:我不会那样做 .

相关问题