如何产生一个等待异步操作的线程?

问题描述 投票:0回答:1

这是我的网络场景:服务器(使用 boost asio 实现)正在接收请求,处理它们,然后传递到多个主机(使用也使用 asio 实现的 http 客户端),等待答案,处理答案,然后回复原始请求。

问题是主机被授予时间限制,服务器在等待答案时必须尊重它(即如果限制是100毫秒,那么服务器无法在100毫秒过去之前关闭连接)。

由于我的服务器正在使用工作线程池(每个线程都在运行

boost::asio::io_service::run()
),如果主机速度慢阻塞等待答案很快就会成为瓶颈(即所有工作人员都忙于等待,无法处理更多请求)。

这是服务器处理程序代码(大部分被跳过)

void connection::handle(asio::yield_context yield)
{
    // read request
    asio::async_read_until(socket_, request_buf, "\r\n", yield);

    // read headers
    asio::async_read_until(socket_, request_buf, "\r\n\r\n", yield);

    // handle request
    // THIS IS BLOCKING CALL
    request_handler_->handle_request(request_, reply_);

    // write reply
    asio::async_write(socket_, reply_.to_buffers(), yield[ec]);
}

这就是handle_request 的作用

http::client::client c(host, port);

// this is asynchronous call returning immediately
std::future<http::reply> res = c.send(request);

// BOTTLENECK PROBLEM HERE
// this is blocking wait for answer
auto reply = res->get();

首先,我可以以异步方式重写

handle_request()
,如下所示:https://stackoverflow.com/a/26728121(这不会解决问题,但可能进一步有用)。我还可以将回调传递给
client::send()
以避免明确得到响应。

我想以某种方式“放弃”阻塞等待,直到收到所有响应,以便工作人员在此期间可以自由地服务其他传入请求。

我尝试了

boost::coroutine
boost::fiber
,但是没有成功,确实这两个只是传递执行上下文,但我没有地方传递上下文,我只需要“等待”。

c++ asynchronous networking boost-asio
1个回答
0
投票

简单的解决方案是使用

boost::asio::deadline_timer
在线程池上进行等待,直到时间限制。

boost::asio::deadline_timer timer(my_context);
timer.expires_from_now(boost::posix_time::milliseconds(100));
timer.async_wait(yield);
© www.soinside.com 2019 - 2024. All rights reserved.