当boost :: asio :: io_service运行方法阻塞/取消阻塞时感到困惑

作为Boost.Asio的初学者,我对感到困惑io_service::run()。如果有人可以向我解释此方法的阻止/解除阻止,我将不胜感激。文档指出:


该run()函数将阻塞,直到所有工作完成并且不再有要分派的处理程序,或者直到io_service停止为止。


多个线程可以调用该run()函数来建立线程池,线程池io_service可以从中执行处理程序。池中等待的所有线程都是等效的,并且io_service可以选择其中任何一个来调用处理程序。


从该run()函数正常退出意味着该io_service对象已停止(该stopped()函数返回true)。后续调用run(),run_one(),poll()或poll_one()将除非有预先调用立即返回reset()。


以下陈述是什么意思?


[...]不再派遣处理程序[...]


在尝试了解的行为时io_service::run(),我遇到了这个示例(示例3a)。在其中,我观察到这些io_service->run()障碍并等待工作指令。


// WorkerThread invines io_service->run()

void WorkerThread(boost::shared_ptr<boost::asio::io_service> io_service);

void CalculateFib(size_t);


boost::shared_ptr<boost::asio::io_service> io_service(

    new boost::asio::io_service);

boost::shared_ptr<boost::asio::io_service::work> work(

   new boost::asio::io_service::work(*io_service));


// ...


boost::thread_group worker_threads;

for(int x = 0; x < 2; ++x)

{

  worker_threads.create_thread(boost::bind(&WorkerThread, io_service));

}


io_service->post( boost::bind(CalculateFib, 3));

io_service->post( boost::bind(CalculateFib, 4));

io_service->post( boost::bind(CalculateFib, 5));


work.reset();

worker_threads.join_all();

但是,在我正在处理的以下代码中,客户端使用TCP / IP连接,并且run方法将阻塞,直到异步接收数据为止。


typedef boost::asio::ip::tcp tcp;

boost::shared_ptr<boost::asio::io_service> io_service(

    new boost::asio::io_service);

boost::shared_ptr<tcp::socket> socket(new tcp::socket(*io_service));


// Connect to 127.0.0.1:9100.

tcp::resolver resolver(*io_service);

tcp::resolver::query query("127.0.0.1", 

                           boost::lexical_cast< std::string >(9100));

tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

socket->connect(endpoint_iterator->endpoint());


// Just blocks here until a message is received.

socket->async_receive(boost::asio::buffer(buf_client, 3000), 0,

                      ClientReceiveEvent);

io_service->run();


// Write response.

boost::system::error_code ignored_error;

std::cout << "Sending message \n";

boost::asio::write(*socket, boost::asio::buffer("some data"), ignored_error);

run()在下面的两个示例中对其描述其行为的任何解释将不胜感激。


jeck猫
浏览 696回答 3
3回答

冉冉说

为了简化run操作,将其视为必须处理一堆纸的员工;它需要一张纸,执行纸页上告诉的内容,将纸页扔掉并拿下另一张纸;当他的床单用完时,它离开了办公室。在每张纸上可以有任何种类的说明,甚至可以在堆中添加一张新纸。回到ASIO:你可以给一个io_service使用:工作有两种方式,本质上post,或者通过使用内部调用其他对象就可以了,你挂在样品中post的io_service一样,socket和它的async_*方法。

精慕HU

可以io_service.poll()用来处理事件循环,而不会阻塞未完成的操作。避免混合同步操作和异步操作的主要建议是避免增加不必要的复杂性,并在处理程序需要很长时间才能完成时防止响应性差。在某些情况下它是安全的,例如当您知道同步操作不会阻塞时。
打开App,查看更多内容
随时随地看视频慕课网APP