boost :: asio :: io_service :: poll()带来的麻烦

时间:2010-06-07 17:25:08

标签: c++ boost boost-asio

以下代码:

/***************************************************************************/

boost::mutex m;

struct func {
   func(int v):n(v) {}
   void operator()() {
      {  boost::mutex::scoped_lock l(m);
         std::cout << "run function " << n << std::endl;
      }
      for ( int idx = 0; idx < 4; ++idx ) {
         {  boost::mutex::scoped_lock l(m);
            std::cout << "function " << n << ", ping " << idx << std::endl;
         }
         sleep(1);
      }
   }

private:
   int n;
};

/***************************************************************************/

int main(int argv, const char** argc) {
   boost::asio::io_service io;

   for ( int idx = 0; idx < 4; ++idx ) {
      io.post(func(idx));
   }

   std::cout << "before run" << std::endl;
   io.poll();
   std::cout << "after run" << std::endl;

   std::cin.get();

   return 0;
}

/***************************************************************************/

给出了这样一个输出:

**before run**
run function 0
function 0, ping 0
function 0, ping 1
function 0, ping 2
function 0, ping 3
run function 1
function 1, ping 0
function 1, ping 1
function 1, ping 2
function 1, ping 3
run function 2
function 2, ping 0
function 2, ping 1
function 2, ping 2
function 2, ping 3
run function 3
function 3, ping 0
function 3, ping 1
function 3, ping 2
function 3, ping 3
**after run**

但是,根据文件:

  

poll()函数运行处理程序   准备好运行,没有阻塞,   直到io_service停止   或者没有更好的处理程序。

poll() - 是一种非阻塞方法。 有什么问题?

和第二个问题: 在文档中,据说:

  

返回那些处理程序的数量   被执行了。

如果它是非阻塞的,它将返回什么值? - 队列中的对象数量? - 但这与“被执行的”不同。

2 个答案:

答案 0 :(得分:13)

这是一个老问题,但你从来没有真正得到关于run vs poll的答案。

io_service :: run将继续运行,只要有事情可做,例如等待截止时间计时器或IO完成通知等。这就是为什么有工作对象保持退出运行的原因。

io_service :: poll只会执行就绪处理程序,并且在没有准备好调度的处理程序之前不会返回。

另一方面,不同之处在于run将等待挂起的处理程序准备就绪,如计时器或IO完成通知,而poll将在该情况下返回。

如果要执行某些空闲处理,此行为很有用。

答案 1 :(得分:4)

非阻塞与异步不同。 pool同步运行准备运行的处理程序,并在不阻塞的情况下返回并等待另一个处理程序。

补充说明。 阻止输入操作是在没有找到输入数据的情况下开始无休止等待的操作。考虑读操作,它应该从某个端口读取一个字节,但没有输入数据。在这种情况下,Read call挂起,仅在收到byte时返回。如果没有输入信息,则非阻塞读取操作立即返回。

池操作是非阻塞的。它同步执行所有挂起的请求并返回。如果没有传入请求,则轮询立即返回。