c - 如何干净地中断 recv 调用中阻塞的线程?

标签 c multithreading sockets pthreads posix

我有一个用 C 编写的多线程服务器,每个客户端线程看起来像这样:

ssize_t n;
struct request request;

// Main loop: receive requests from the client and send responses.
while(running && (n = recv(sockfd, &request, sizeof(request), 0)) == sizeof(request)) {
    // Process request and send response.
}
if(n == -1)
    perror("Error receiving request from client");
else if(n != sizeof(act))
    fprintf(stderr, "Error receiving request from client: Incomplete data\n");

// Clean-up code.

在某些时候,客户端满足一定的条件,它必须断开连接。如果客户端定期发送请求,这很好,因为它可以在响应中被告知断开连接;然而,有时客户端需要很长时间才能发送请求,因此客户端线程最终会阻塞在 recv 调用中,并且在下一个请求/响应之前客户端不会断开连接。

当客户端线程在 recv 调用中阻塞时,是否有一种干净的方法可以断开客户端与另一个线程的连接?我尝试了 close(sockfd) 但这会导致错误 Error receiving request from client: Bad file descriptor 发生,这确实不准确。

或者,有没有更好的方法让我在这里处理错误?

最佳答案

所以你至少有这些可能性:

(1) pthread_kill 将使用 errno == EINTR 将线程从 recv 中清除,您可以自行清理并退出线程。有些人认为这是令人讨厌的。视情况而定。

(2) 使您的客户端套接字成为非阻塞的,并使用 select 等待输入一段时间,然后检查线程之间使用的开关是否已设置为 indicated他们应该关闭。

(3) 结合 (2) 让每个线程与主线程共享一个管道。将其添加到 select。如果它变得可读并包含一个 shutdonw 请求,线程将自行关闭。

(4) 如果以上(或其变体)都不满足您的需求,请查看pthread_cancel 机制。

关于c - 如何干净地中断 recv 调用中阻塞的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17822025/

相关文章:

c - 如何处理 ruby​​ ffi gem 中的 ruby​​ 数组?

python - 尝试连接套接字时出现错误 10051

Java程序阻塞端口?

c++ - 发布和调试编译程序的源代码是否有所不同? [C/C++]

C - 将枚举用于位标志 - 警告 : enumerated type mixed with another type

c - 需要处理大量定时器/超时的建议

python - 如何实现暂停(和更多)功能?

java - 线程中的 MouseMotionListener

macos - Mac OS X 上与防火墙相关的奇怪套接字泄漏

C 代码在 Linux Debian 中编译失败