无法处理 boost asio:异步读取缓冲区的回调异步。

huangapple go评论76阅读模式
英文:

Unable to process boost asio:- async read buffer's callback asynchronously

问题

我使用boost::asio::async_read()方法来异步获取来自服务器的响应,该服务器需要10秒来处理请求。我成功地读取了响应。但我附加了回调函数来处理接收到的响应,这需要10秒的时间。我不知道如何异步处理该回调。

void read_response(std::string data)
{
    cout << data << endl;
    sleep(10);
    // 如果您认为 sleep 会以不同的方式工作,如果我从这里发送另一个 REST API 请求,仍然会阻止处理该函数
}
boost::asio::async_read(socket, boost::asio::buffer(buffer), [&](const boost::system::error_code&
                                                                     error,
                                                                 std::size_t bytes_transferred) {
    io_context.post([&]() {
        read_response(buffer.data());
        // read_response 不会异步处理
    });
});

我尝试将函数发布到 io_context,我尝试使用

std::async(std::launch::deferred, read_handler, error, bytes_transferred, buffer.data()).wait();

我是异步编程和C++编程的新手。

英文:

I'm using boost::asio::async_read() method to asynchronously get response from server which take 10 second to process request. I am able to read response successfully. but I am attaching callback to this function to process received response which take 10 seconds. I am unable to find how i can process that callback asynchronously.

void read_response(std::string data)
{
    cout &lt;&lt; data &lt;&lt; endl;
    sleep(10);
    // if you think sleep works differently if i send another rest api request from here still this function blocks the processing
}
boost::asio::async_read(socket, boost::asio::buffer(buffer), [&amp;](const boost::system::error_code&amp;
                                                                     error,
                                                                 std::size_t bytes_transferred) {
    io_context.post([&amp;]() {
        read_response(buffer.data());
        //read_response is not processing asynchronously
    });
});

I tried posting function to io_context, i tried using

std::async(std::launch::deferred, read_handler,error,bytes_transferred,buffer.data()).wait() ;

I am new to asyn programming and c++ programming.

答案1

得分: 1

以下是您要翻译的部分:

Indeed, don't do blocking operations on the IO service. Or grow the thread pool to accomodate for the maximum number of concurrent tasks that must be supported.

In all circumstances, copy the message into your read handler, instead of passing the buffer directly (as you did) as that invites race conditions/stale references.

Let's demonstrate using httpbin.org/delay:

Live On Coliru

#include <boost/asio.hpp>
#include <iomanip>
#include <iostream>

namespace asio = boost::asio;
using asio::ip::tcp;
using namespace std::chrono_literals;

std::string const request = "GET /delay/10 HTTP/1.1\r\nHost: httpbin.org\r\n\r\n";

void read_response(std::string data) {
    std::cout << "Asynchronously received response: " << quoted(data) << std::endl;
    sleep(10);
}

int main() {
    asio::io_context  ioc(1);
    asio::thread_pool work(10); // support 10 tasks along-side async IO

    tcp::socket conn(ioc);
    connect(conn, tcp::resolver(ioc).resolve("httpbin.org", "80"));
    write(conn, asio::buffer(request));

    std::string buf;
    async_read_until( //
        conn, asio::dynamic_buffer(buf), "\r\n\r\n",
        [&work, &buf](boost::system::error_code ec, size_t n) {
            std::cout << "\n*** Completion " << ec.message() << ", " << n << std::endl;

            post(work, [msg = buf.substr(0, n)] {
                // NOTE: lambda owns msg, not a reference to `buf`
                read_response(std::move(msg));
            });
        });

    std::thread([&ioc] {
        ioc.run();
        std::cout << "\n*** IO complete" << std::endl;
    }).detach();

    for (int i = 0; i < 15; ++i) {
        std::cout << "." << std::flush;
        std::this_thread::sleep_for(1s);
    }

    work.join();
    std::cout << "\n*** Work Done" << std::endl;
}

This shows work continuing, "asynchronously" (relative to IO) well after ioc completes.

英文:

Indeed, don't do blocking operations on the IO service. Or grow the thread pool to accomodate for the maximum number of concurrent tasks that must be supported.

In all circumstances, copy the message into your read handler, instead of passing the buffer directly (as you did) as that invites race conditions/stale references.

Let's demonstrate using httpbin.org/delay:

Live On Coliru

#include &lt;boost/asio.hpp&gt;
#include &lt;iomanip&gt;
#include &lt;iostream&gt;

namespace asio = boost::asio;
using asio::ip::tcp;
using namespace std::chrono_literals;

std::string const request = &quot;GET /delay/10 HTTP/1.1\r\nHost: httpbin.org\r\n\r\n&quot;;

void read_response(std::string data) {
    std::cout &lt;&lt; &quot;Asynchronously received response: &quot; &lt;&lt; quoted(data) &lt;&lt; std::endl;
    sleep(10);
}

int main() {
    asio::io_context  ioc(1);
    asio::thread_pool work(10); // support 10 tasks along-side async IO

    tcp::socket conn(ioc);
    connect(conn, tcp::resolver(ioc).resolve(&quot;httpbin.org&quot;, &quot;80&quot;));
    write(conn, asio::buffer(request));

    std::string buf;
    async_read_until( //
        conn, asio::dynamic_buffer(buf), &quot;\r\n\r\n&quot;,
        [&amp;work, &amp;buf](boost::system::error_code ec, size_t n) {
            std::cout &lt;&lt; &quot;\n*** Completion &quot; &lt;&lt; ec.message() &lt;&lt; &quot;, &quot; &lt;&lt; n &lt;&lt; std::endl;

            post(work, [msg = buf.substr(0, n)] {
                // NOTE: lambda owns msg, not a reference to `buf`
                read_response(std::move(msg));
            });
        });

    std::thread([&amp;ioc] {
        ioc.run();
        std::cout &lt;&lt; &quot;\n*** IO complete&quot; &lt;&lt; std::endl;
    }).detach();

    for (int i = 0; i &lt; 15; ++i) {
        std::cout &lt;&lt; &quot;.&quot; &lt;&lt; std::flush;
        std::this_thread::sleep_for(1s);
    }

    work.join();
    std::cout &lt;&lt; &quot;\n*** Work Done&quot; &lt;&lt; std::endl;
}

This shows work continuing, "asynchronously" (relative to IO) well after ioc completes:

无法处理 boost asio:异步读取缓冲区的回调异步。

huangapple
  • 本文由 发表于 2023年2月16日 03:28:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75464590.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定