我试图了解并行线程上套接字API( recv
, send
, select
, close
等)的用法 . 这意味着在两个并行线程上使用一个套接字文件描述符我已经完成了this问题 . 但我仍然无法找到任何解释多线程中套接字API用法的标准文档 . 甚至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, ..)
...
}
}
1 回答
Posix functions are thread-safe "by default":
正如许多人已经评论过的那样,您可以安全地从不同的线程调用上述调用 .
Case "1"和"2"非常典型(一个线程接收,一个发送,每个线程处理许多与
select()
的连接)用于 生产环境 代码 .Case "3"在某种程度上是奇怪的,可能是麻烦的来源(它会起作用,调用是有效的,但是获得所需的行为可能并不简单) . 通常,您可以在开始时将套接字置于非阻塞模式,并在
send()
/recv()
调用或阻塞中处理EAGAIN / EWOULDBLOCK错误并使用select()
/pselect()
/poll()
/ppoll()
.在这种情况下,发送线程将随机“查找”处于阻塞或非阻塞模式的套接字:我不会那样做 .