6

我正在尝试了解并行线程上套接字 API(recvsendselectclose等)的使用。这意味着在两个并行线程上使用一个套接字文件描述符。我已经解决了这个问题。但是我仍然找不到任何标准文档来解释多线程中套接字 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)在两个并行线程中调用recvand sendwithselect

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 )在两个并行线程中调用recvand send, setsockopt,ioctlfcntl

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

1 回答 1

3

Posix 函数“默认”是线程安全的

2.9.1 线程安全

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

正如许多人已经评论的那样,您可以安全地从不同的线程调用提到的调用。

select()案例“1”和“2”对于生产代码来说是非常典型的(一个线程接收,一个发送,每个线程处理许多与 的连接)。

案例“3”有点奇怪,可能是麻烦的根源(它会起作用,调用是有效的,但获得所需的行为可能并不简单)。通常,您要么在开始时将套接字置于非阻塞模式并处理send()/recv()调用中的 EAGAIN/EWOULDBLOCK 错误,要么阻塞并使用select()/ pselect()/ poll()/ ppoll()

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

于 2016-03-31T08:58:28.467 回答