boost::asio::io_service的stop()和reset()和stopped()函数

◆boost::asio::io_service使用时的注意事项:

①请让boost::asio::io_service和boost::asio::io_service::work搭配使用。

②想让event按照进入(strand)时的顺序被执行,需要boost::asio::io_service要和boost::asio::io_service::strand搭配使用。

③一般情况下,io_service的成员函数的使用顺序:

boost::asio::io_service构造,
boost::asio::io_service::run(),
boost::asio::io_service::stop(),
boost::asio::io_service::reset(),
boost::asio::io_service::run(),
......
boost::asio::io_service析构,
④不论有没有使用io_service::work,run()都会执行完io_service里面的event,(若没有用work,run就会退出)。
⑤一个新创建的io_service不需要执行reset()函数。
⑥在调用stop()后,在调用run()之前,请先调用reset()函数。
⑦函数stop()和reset()并不能清除掉io_service里面尚未执行的event。
我个人认为,也只有析构掉io_service,才能清空它里面的那些尚未执行的event了。(可以用智能指针)。

⑧函数stop(),stopped(),reset(),很简单,请单步调试,以明白它在函数里做了什么。

⑨boost的.hpp文件里面(一般情况下)有各个函数的使用说明,你可以随时查看。

◆下面是boost::asio::io_service的stop()和reset()函数的注释的翻译:

void boost::asio::io_service::stop();
BOOST_ASIO_DECL void stop();
/// Stop the io_service object's event processing loop.
/// 停止io_service对象的事件处理循环。
/**
 * This function does not block, but instead simply signals the io_service to
 * stop. All invocations of its run() or run_one() member functions should
 * return as soon as possible. Subsequent calls to run(), run_one(), poll()
 * or poll_one() will return immediately until reset() is called.
 */
 /**
 这个函数不阻塞,而是仅仅表示io_service停止了。
 它的run()或run_one()成员函数的调用应当尽快返回。
 对run()、run_one()、poll()、poll_one()的随后的调用将会立即返回直到reset()函数被调用了。
 */
void boost::asio::io_service::reset();
BOOST_ASIO_DECL void reset();
/// Reset the io_service in preparation for a subsequent run() invocation.
/// 重置io_service对象,为随后的run()调用做准备。
/**
 * This function must be called prior to any second or later set of
 * invocations of the run(), run_one(), poll() or poll_one() functions when a
 * previous invocation of these functions returned due to the io_service
 * being stopped or running out of work. After a call to reset(), the
 * io_service object's stopped() function will return @c false.
 *
 * This function must not be called while there are any unfinished calls to
 * the run(), run_one(), poll() or poll_one() functions.
 */
 /**
 io_service被停止,或者执行完handler而缺乏工作时,run()、run_one()、poll()、poll_one()函数的调用会被返回。
 这些函数在被调用之前,必须先调用reset函数。
 在reset函数被调用后,io_service对象的stopped函数将会返回false。
 当run()、run_one()、poll()、poll_one()函数的任何的调用未结束时,这个函数一定不能被调用。
 */

◆对stop()和reset()函数的一点说明(是我单步调试时看到的):

在Windows下,boost::asio::io_service类里面有一个数据成员为"stopped_"(Flag to indicate whether the event loop has been stopped.)。它是一个标志,它标志着事件循环是不是被stopped了。而boost::asio::io_service::reset()函数仅仅是赋值"stopped_=0"。boost::asio::io_service::stopped()函数仅仅是判断"0!=stopped_"的真假。你单步调试一下,就什么都知道了。

◆下面是我验证boost::asio::io_service的一个例子:

[cpp]  view plain  copy
  1. #include <boost/asio.hpp>  
  2. #include <boost/thread.hpp>  
  3. #include <boost/atomic.hpp>  
  4. #include <boost/shared_ptr.hpp>  
  5. #include <boost/date_time/posix_time/ptime.hpp>  
  6. #include <boost/date_time.hpp>//boost::posix_time::to_iso_extended_string()需要此头文件。  
  7.   
  8. //boost::atomic_bool coutFlag = false;  
  9. //error C2440: 'initializing' : cannot convert from 'bool' to 'boost::atomics::atomic<bool>'  
  10. //故意写错,可以根据错误信息知道某类型的详细信息。  
  11. boost::atomic_bool g_coutFlag(false);  
  12. boost::atomic_int g_numIn(0);  
  13. boost::atomic_int g_numOut(0);  
  14.   
  15. boost::thread_group g_thgp;  
  16. boost::asio::io_service g_io;  
  17. boost::shared_ptr<boost::asio::io_service::work> g_pWork = \  
  18. boost::shared_ptr<boost::asio::io_service::work>(new boost::asio::io_service::work(g_io));  
  19. boost::asio::io_service::strand g_strand(g_io);  
  20. std::vector<boost::posix_time::ptime> g_vecTimes;  
  21.   
  22. void my_run_4_io_service(boost::asio::io_service& _io, int _idx)  
  23. {  
  24.     _io.run();  
  25.     //想得到boost::asio::io_service::run()退出时的时刻,只能对io_service进行封装了。  
  26.     g_vecTimes[_idx] = boost::posix_time::microsec_clock::local_time();  
  27. }  
  28.   
  29. void outFun(int idx)  
  30. {// io_service执行的handler。  
  31.     ++g_numOut;  
  32.     if (g_coutFlag.load())  
  33.         std::cout << "outFun: index=" << idx << std::endl;  
  34.     boost::this_thread::sleep_for(boost::chrono::milliseconds(500));  
  35. }  
  36.   
  37. void inFun()  
  38. {  
  39.     for (int i = 1; i <= 10; ++i)  
  40.     {  
  41.         g_strand.post(boost::bind(outFun, i));  
  42.         ++g_numIn;  
  43.         boost::this_thread::sleep_for(boost::chrono::milliseconds(100));  
  44.     }  
  45.     g_coutFlag = true;  
  46.     g_io.stop();//调用它后,不论io_service有没有使用io_service::work类,各个线程的run()都会立即返回。  
  47.     g_vecTimes[0] = boost::posix_time::microsec_clock::local_time();  
  48.     int numDelta = g_numIn - g_numOut;  
  49.     std::cout << "inFun: numDelta=" << numDelta << std::endl;//还剩多少event没有被执行。  
  50. }  
  51.   
  52. int main()  
  53. {  
  54.     int vecNum = 5;  
  55.     g_vecTimes.reserve(vecNum); g_vecTimes.resize(vecNum);  
  56.     //一个容纳 void fun(int i) 函数的 function对象。  
  57.     boost::function<void(int)> my_lambda_function_object = [vecNum](int secs)  
  58.     {  
  59.         boost::this_thread::sleep_for(boost::chrono::microseconds(1000 * 1000 * secs));  
  60.         std::cout << "now, time is " << boost::posix_time::  
  61.             to_iso_extended_string(boost::posix_time::microsec_clock::local_time()) << std::endl;  
  62.         for (int i = 0; i < vecNum; ++i)  
  63.             std::cout << i << " : " << boost::posix_time::to_iso_extended_string(g_vecTimes[i]) << std::endl;  
  64.     };  
  65.   
  66.     for (int i = 1; i < vecNum; ++i)  
  67.         g_thgp.create_thread(boost::bind(my_run_4_io_service, boost::ref(g_io), i));  
  68.     g_thgp.create_thread(inFun);  
  69.     //等待5秒,确保执行完毕我设计的那些操作。  
  70.     my_lambda_function_object(5);  
  71.     //析构掉io_service对应的io_service::work对象,此时io_service里面还有event。  
  72.     g_pWork = nullptr;  
  73.     boost::this_thread::sleep_for(boost::chrono::milliseconds(1000 * 1));  
  74.     g_io.reset();  
  75.     boost::this_thread::sleep_for(boost::chrono::seconds(1));  
  76.     //因为work被析构掉了,所以启动的那些线程在执行完event后,都自行退出了。  
  77.     for (int i = 1; i < vecNum; ++i)  
  78.         g_thgp.create_thread(boost::bind(my_run_4_io_service, boost::ref(g_io), i));  
  79.     //等待6秒,确保io_service中剩余的event被执行完毕。  
  80.     my_lambda_function_object(6);  
  81.     std::cout << "done." << std::endl;  
  82.     int cmd_val = getchar();  
  83.     return 0;  
  84. }  
完。

猜你喜欢

转载自blog.csdn.net/i7thtool/article/details/80470942