Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 启动boost::asio::io_服务时的例程_C++_Multithreading_Boost Asio_Boost Thread - Fatal编程技术网

C++ 启动boost::asio::io_服务时的例程

C++ 启动boost::asio::io_服务时的例程,c++,multithreading,boost-asio,boost-thread,C++,Multithreading,Boost Asio,Boost Thread,我想使用boost asio创建一个http客户端。为了有一个结构化和优化的应用程序,我研究了boost asio的示例,以了解一个好的实现应该是什么样子 大多数情况下,我遵循的是的结构,因此我有一个连接管理器,它保存一组指向每个单独连接的指针。现在,这里最大的区别是在server.cpp的构造函数中已经调用了一个异步函数,即 acceptor_.async_accept(new_connection_->socket(), boost::bind(&server::handle_a

我想使用boost asio创建一个http客户端。为了有一个结构化和优化的应用程序,我研究了boost asio的示例,以了解一个好的实现应该是什么样子

大多数情况下,我遵循的是的结构,因此我有一个连接管理器,它保存一组指向每个单独连接的指针。现在,这里最大的区别是在server.cpp的构造函数中已经调用了一个异步函数,即

acceptor_.async_accept(new_connection_->socket(), boost::bind(&server::handle_accept, this, boost::asio::placeholders::error)); acceptor\异步\u accept(新建\u连接->套接字(), boost::bind(&server::handle_accept),这, boost::asio::占位符::错误); 在winmain.cpp中,io_服务通过对server::run()的函数调用启动:

io_服务_uu.run(); 在我的实现中,因为它是一个客户端而不是服务器,所以我希望在开始连接到服务器之前等待用户调用send()函数。因此,我将所有与服务器连接相关的函数调用移到了connection类中。当用户请求向服务器发送消息时,调用以下命令:

resolver.async_resolve(query, boost::bind(&connection::handle_resolve, boost::ref(*this), boost::asio::placeholders::error, boost::asio::placeholders::iterator)); io_service_.run(); 解析程序.async\u解析(查询, boost::bind(&connection::handle_resolve,boost::ref(*this), boost::asio::占位符::错误, boost::asio::占位符::迭代器); io_服务_uu.run(); 我想在一个单独的线程中启动每个连接对象,这就是我问题的背景。我如何做到这一点,以获得结构化和优化的代码

例如,我尝试设置io_服务的线程池,并将工作分配给它们,以便它们在停止之前不会返回。这似乎是个好主意,因为我会让io服务一直在后台运行。因此,我从等效于server.cpp的线程池启动线程:

boost::thread t(boost::bind(&geocast::enabler::io_service_pool::run, &io_service_pool_)); boost::线程t(boost::bind(&geocast::enabler::io_服务_池::运行,&io_服务_池)); 但是,根据我自己的试错分析,在发出异步函数之前,似乎无法启动io_服务,这是真的吗?因为我的程序卡住了。在我的例子中,我只想在用户想要发送POST请求或GET请求时调用async_resolve。支持我的理论;首先调用一个async_connect并将async_读取为回调,这样他们就可以在创建客户端之后安全地调用io_service.run()。我不想为了启动io_服务而一直从服务器上读取数据,因为这不是普通客户端的工作方式,对吗?如果用户没有浏览到某个网站,浏览器就无法读取地球上所有可能的服务器

如果我不使用示例2中的线程池,而是在一个单独的类中启动每个连接类,每个类都有自己的io_服务,那么一切都可以正常工作。但是,一个线程池和一个简单的循环例程来选择合适的io_服务似乎真的很吸引人。对于我来说,使用多线程的最佳方法是什么?我只是挑剔,应该坚持一个连接一个io的服务吗

我已经试过了,作为HTTP服务器2 例如,设置的线程池 io_服务和分配工作给他们 这样他们就不会回来,直到 停下来

在使用异步编程时,我强烈建议按顺序使用以下设计:

  • 单线程的单
    io_服务
  • 调用单个
    io\u服务的线程池
  • io_服务
    每线程或其他异国设计
  • 只有在分析之后,当前设计被证明是瓶颈时,才应该转移到下一个设计

    但是,从我自己的尝试和错误 分析,似乎你无法开始 在您发出 异步函数,是这样吗

    您是对的,
    io\u服务::run()
    非常清楚地说明了这一点

    函数的作用是:直到所有 工作已经完成,没有工作了 要分派更多处理程序,或 直到io_服务停止


    防止
    io\u service::run()
    立即返回的正确方法是将一些处理程序排队,或实例化
    io\u service::work
    ,并将其保持在范围内,直到
    run()
    保持活动状态。

    使用ASIO时,您放弃了对ASIO程序流的控制。如果您将代码更改为使用线程池并调用而不是调用,则可以共享控制权。run_one()只将一个IO作业分派给一个线程,因此如果ioservice中有多个事件,则必须多次调用run_one()


    您是否想过生成一个新线程作为您的boss线程,然后让您的boss线程创建一组工作线程?您的boss线程可以调用run(),然后您的UI线程可以调用以分派新的工作单元。除了不必在ioservice中手动调用和调度任务外,它还可以使清理和关闭更直接,因为您的boss线程在调用run()时会阻塞。

    感谢您的良好反馈!关于io_服务::run():我所说的“之前无法启动io_服务”的意思是:我首先创建一个客户端对象,它有一个在线程中运行的函数。然后调用客户端类中的send()函数。现在,这就是它变得棘手的地方;在客户机类中,调用async_resolve()。同时,在主线程中,io_服务通过run()启动,即在主线程中首先调用send()函数,然后调用io_服务.run()。但是这个程序只是被卡住了。为什么?“看来work()帮不了什么忙……”托马斯问了一个新问题,我不清楚根据评论你想完成什么。 boost::thread t(boost::bind(&geocast::enabler::io_service_pool::run, &io_service_pool_));