如何干净地中断recv调用中的线程阻塞? [英] How to cleanly interrupt a thread blocking on a recv call?

查看:217
本文介绍了如何干净地中断recv调用中的线程阻塞?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a multithreaded server written in C, with each client thread looking something like this:

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调用中阻塞,并且直到下一个请求/响应,客户端才断开连接.

At some point, a client meets a certain criteria where it must be disconnected. If the client is regularly sending requests, this is fine because it can be informed of the disconnection in the responses; However sometimes the clients take a long time to send a request, so the client threads end up blocking in the recv call, and the client does not get disconnected until the next request/response.

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

Is there a clean way to disconnect the client from another thread while the client thread is blocking in the recv call? I tried close(sockfd) but that causes the error Error receiving request from client: Bad file descriptor to occur, which really isn't accurate.

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

Alternatively, is there a better way for me to be handling errors here?

推荐答案

因此,您至少具有以下可能性:

So you have at least these possibilities:

(1)pthread_kill将使用errno == EINTR将线程吹出recv,您可以自行清理并退出线程.有人认为这很讨厌.确实取决于.

(1) pthread_kill will blow the thread out of recv with errno == EINTR and you can clean up and exit the thread on your own. Some people think this is nasty. Depends, really.

(2)使您的客户端套接字不阻塞,并使用select在特定时间段内等待输入,然后检查是否已将线程之间使用的开关设置为指示它们应该关闭.

(2) Make your client socket(s) non-blocking and use select to wait on input for a specific period of time before checking if a switch used between the threads has been set to indicated they should shut down.

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

(3) In combo with (2) have each thread share a pipe with the master thread. Add it to the select. If it becomes readable and contains a shutdonw request, the thread shuts itself down.

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

(4) Look into the pthread_cancel mechanism if none of the above (or variations thereof) do not meet your needs.

这篇关于如何干净地中断recv调用中的线程阻塞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆