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

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

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发生Error receiving request from client: Bad file descriptor ,这实际上是不准确的。

或者,我有更好的方法来处理错误吗?

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

(1) pthread_kill会使用errno == EINTR将线程从recv删除,您可以自行清理并退出该线程。 有些人认为这很讨厌。 真的,取决于。

(2)使客户端套接字无阻塞,并使用select等待输入一段特定的时间,然后检查线程之间使用的交换机是否已设置为表示应该关闭。

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

(4)如果上述(或其变体)都不符合您的需要,请查看pthread_cancel机制。

关闭套接字以从另一个线程输入。 这将导致读取线程接收EOS,这应该导致它关闭套接字并在正确写入时终止。