gpt4 book ai didi

c++ - Boost asio 用于多个异步网络客户端操作

转载 作者:行者123 更新时间:2023-11-30 03:53:21 24 4
gpt4 key购买 nike

我想使用 boost::asio(或独立的 asio)通过异步套接字每分钟查询一次多个网络设备的数据。对于测试,我已经实现了一个客户端类和一个控制台程序,该程序为一个设备执行此操作(无需重复)。像这样:

class MyClient
{
public:
MyClient(asio::io_service& io_service);

void GetData(CompletionHandler completionHandler);
};

MyClient::GetData 类在内部使用多个异步操作,其中每个操作的完成都会触发下一个操作,直到数据可用为止:

  • 连接
  • 阅读标题
  • 读取数据
  • 断开连接

使用这个类的控制台程序是这样工作的:

int main(...)
{
asio::io_service io_service_;

MyClient c(io_service_, ...);
...
c.GetData([](std::error_code ec, const FloatVector& values){
//do something with values
});

io_service_.run();
...
}

现在我想在 GUI 程序中使用 MyClient 类来每分钟连接到 >10 台设备一次,但我坚持整体设计。

首先,我创建了一个线程池,其中每个线程执行单个 io_service 实例的 io_service::run()。

现在,每当我的程序想要从设备读取数据时,它都会在所有设备上循环,并且必须为每个设备创建一个 MyClient 实例并调用 GetData() 方法。

既然 io_service::run() 在池的线程中执行,它如何与 io_service 一起工作?我可以在 GUI 线程中简单地调用 MyClient::GetData() 吗,因为它在内部使用异步操作,或者我必须调用类似 io_service::post() 的东西吗?

更新:我的代码和控制台演示大致遵循这个例子:www.boost.org/doc/libs/1_36_0/doc/html/boost_asio/example/http/client/async_client.cpp

但在 GUI 程序中,我不想在 GUI 线程中运行 io_service.run()。现在假设我至少有一个执行 io_service.run() 的额外线程,并且用户按下了一个应该开始设备读取的按钮。最终完成处理程序应将数据存储在数据库中并更新图形显示给用户。

也许按钮处理程序可以简单地实例化 MyClient 并在其上调用 GetData() 并且一切正常,因为 MyClient 知道 io_service 并使用它 f.e.在 async_connect 等中。

它是这样工作的还是我弄错了?

注意:此时我的问题不是如何处理完成处理程序中的数据!就是如何在多线程GUI程序中正确获取数据。

最佳答案

以下是您需要做的事情的粗略概述:

  • 首先请注意,如果 io_service.run() 没有工作要做,它会立即返回。因此,根据您的工作流程,您可能需要推迟调用它,直到您真正将第一个异步连接排队。如果您查看示例客户端,您会看到首先实例化客户端,该客户端将第一个操作排队(在本例中为异步解析),然后调用 io_service.run()。
  • 因此假设您开始按下按钮,此时您需要做的是安排连接或解析,然后启动一个新线程并从该线程调用 io_service.run()。
  • 一旦异步操作链完成并且您拥有数据,您的处理程序将在您启动的新线程的上下文中被调用。这意味着您必须向 UI 发回消息(因为通常 UI 工作只能在主线程上完成)。例如。您示例中的 lambda 需要执行某种 UI 发布消息操作(详细信息取决于我们在这里讨论的操作系统/GUI)。
  • 然后您的 GUI 线程将获取该消息并更新您想要更新的任何 UI 状态(例如显示结果)

关于c++ - Boost asio 用于多个异步网络客户端操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30146552/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com