asio 03
ã¯ããã«
ä»åã¯ã³ã¼ããéåæåããä¸ã§èã¨ãªã io_service ã«ã¤ãã¦åãä¸ããã
ããã¡ã
ååã¾ã§ãµã³ãã«ã³ã¼ãã«ã¤ãã¦ä¸å解説ãå ¥ãã¦ããªãã£ãããååå¯ãã«ä»¥ä¸ã®ãããªå¼ã³åºããè¡ã£ã¦ããã
io_service.run();
ãããå¼ã³åºãã¨ãä½ãèµ·ããã®ã ãããã以ä¸ã®ãã¨ãèµ·ããã
- å¼ã³åºãåã¾ã§ã«ãã¾ã£ã¦ããéåæå¼ã³åºãå¦çãåãåºã
- éåæå¦çãçµããã¾ã§å¾
ã¤
- ã¤ãã³ãã«ã¼ããå®è¡ããã
ãªã®ã§ãéåæå¦çããããå¼ã³åºãã¦ããio_service::run ãå®è¡ãããªãã¨ä½ãèµ·ãããªããéã«ãéåæå¦çãå¼ã³åºãåã« io_service::run ãå®è¡ããã¦ãã¾ãã¨ããã«å¦çãå®äºãã¦ãã¾ããååã®ã³ã¼ããããio_service::run ã®è¡ãã³ã¡ã³ãã¢ã¦ãå®è¡ãã¦ã¿ãã¨ããåããã¯ãã ãããã«ãããªããã³ã¡ã³ãã¢ã¦ãããããä¸ã«æ°ç§éå¾ æ©ããã³ã¼ãï¼Windows ãªã Sleep ãªã©ï¼ãæ¸ãã¨ããã«ç´å¾ã§ããã ããã
- éåæå¦çãå¼ã³åºããå¾å®éã®å¦çãå®äºããã«ããã«çµäºãã¦ãã¾ãã³ã¼ã
#define _WIN32_WINDOWS 0x0400 #define _WIN32_WINNT 0x400 #include <iostream> #include <boost/array.hpp> #include <asio.hpp> using asio::ip::tcp; void on_resolve( const asio::error_code& error, tcp::resolver::iterator endpoint_iterator ) { if ( ! error ) { tcp::resolver::iterator end; while ( endpoint_iterator != end ) { tcp::endpoint endpoint = endpoint_iterator->endpoint(); std::cout << " capacity: " << endpoint_iterator->endpoint().capacity() << std::endl; std::cout << " data : " << endpoint_iterator->endpoint().data() << std::endl; std::cout << " port : " << endpoint_iterator->endpoint().port() << std::endl; std::cout << " size : " < <endpoint_iterator->endpoint().size() << std::endl; // print address info. asio::ip::address address = endpoint.address(); std::cout << " address : " << address.to_string() << std::endl; std::cout << " is_v4 : " << address.is_v4() << std::endl; std::cout << " is_v6 : " << address.is_v6() << std::endl; std::cout << std::endl; endpoint_iterator++; } } else { std::cerr << error.message() << std::endl; } } int main( int argc, char* argv[] ) { try { if ( argc != 3 ) { std::cerr << "Usage: resolver <host> <service>" << std::endl; return 1; } asio::io_service io_service; tcp::resolver resolver( io_service ); tcp::resolver::query query( argv[1], argv[2] ); // print query info. std::cout << query.host_name() << std::endl; std::cout << query.service_name() << std::endl; std::cout << std::endl; // start to resolve. resolver.async_resolve( query, on_resolve ); //io_service.run(); } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; } return 0; }
- éåæå¦çãå¼ã³åºãã¦ãããããå¾ ã£ã¦ãå®éã®å¦çãå®è¡ãããªãã³ã¼ã
#define _WIN32_WINDOWS 0x0400 #define _WIN32_WINNT 0x400 #include <iostream> #include <boost/array.hpp> #include <asio.hpp> using asio::ip::tcp; void on_resolve( const asio::error_code& error, tcp::resolver::iterator endpoint_iterator ) { if ( ! error ) { tcp::resolver::iterator end; while ( endpoint_iterator != end ) { tcp::endpoint endpoint = endpoint_iterator->endpoint(); std::cout << " capacity: " << endpoint_iterator->endpoint().capacity() << std::endl; std::cout << " data : " << endpoint_iterator->endpoint().data() << std::endl; std::cout << " port : " << endpoint_iterator->endpoint().port() << std::endl; std::cout << " size : " << endpoint_iterator->endpoint().size() << std::endl; // print address info. asio::ip::address address = endpoint.address(); std::cout << " address : " << address.to_string() << std::endl; std::cout << " is_v4 : " << address.is_v4() << std::endl; std::cout << " is_v6 : " << address.is_v6() << std::endl; std::cout << std::endl; endpoint_iterator++; } } else { std::cerr << error.message() << std::endl; } } int main( int argc, char* argv[] ) { try { if ( argc != 3 ) { std::cerr << "Usage: resolver <host> <service>" << std::endl; return 1; } asio::io_service io_service; tcp::resolver resolver( io_service ); tcp::resolver::query query( argv[1], argv[2] ); // print query info. std::cout << query.host_name() << std::endl; std::cout << query.service_name() << std::endl; std::cout << std::endl; // start to resolve. resolver.async_resolve( query, on_resolve ); //io_service.run(); Sleep( 60 * 1000 ); } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; } return 0; }
ããã§åé¡ã«ãªãã®ãããã«ãã¹ã¬ããã¢ããªã±ã¼ã·ã§ã³ãªã©ã§ io_service::run ãå®è¡ãããå¾ã«ã¢ããªã±ã¼ã·ã§ã³ãéåæå¦çãè¡ãã«ã¯ã©ãããããã¨ãããã¨ã ãããã¯ãio_service::work ã¨ããã¯ã©ã¹ã使ããã¨ã§å¯¾å¿ã§ããã
- éåæå¦çãå¼ã³åºããªãã¦ããã£ã¨ io_service::run ããã£ã¨å¾ æ©ãã¦ãããã³ã¼ã
#define _WIN32_WINDOWS 0x0400 #define _WIN32_WINNT 0x400 #include <iostream> #include <boost/array.hpp> #include <asio.hpp> using asio::ip::tcp; void on_resolve( const asio::error_code& error, tcp::resolver::iterator endpoint_iterator ) { if ( ! error ) { tcp::resolver::iterator end; while ( endpoint_iterator != end ) { tcp::endpoint endpoint = endpoint_iterator->endpoint(); std::cout << " capacity: " << endpoint_iterator->endpoint().capacity() << std::endl; std::cout << " data : " << endpoint_iterator->endpoint().data() << std::endl; std::cout << " port : " << endpoint_iterator->endpoint().port() << std::endl; std::cout << " size : " << endpoint_iterator->endpoint().size() << std::endl; // print address info. asio::ip::address address = endpoint.address(); std::cout << " address : " << address.to_string() << std::endl; std::cout << " is_v4 : " << address.is_v4() << std::endl; std::cout << " is_v6 : " << address.is_v6() << std::endl; std::cout << std::endl; endpoint_iterator++; } } else { std::cerr << error.message() << std::endl; } } int main( int argc, char* argv[] ) { try { if ( argc != 3 ) { std::cerr << "Usage: resolver <host> <service>" << std::endl; return 1; } asio::io_service io_service; asio::io_service::work work( io_service ); tcp::resolver resolver( io_service ); tcp::resolver::query query( argv[1], argv[2] ); // print query info. std::cout << query.host_name() << std::endl; std::cout << query.service_name() << std::endl; std::cout << std::endl; // start to resolve. //resolver.async_resolve( query, on_resolve ); io_service.run(); } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; } return 0; }
ãã®ã³ã¼ãã§ãªã io_service::run ããã£ã¨å¾ æ©ãã¦ãããã®ãã¨ããã¨ãé¢é£ã¥ãããã io_service::work ãç ´æ£ãããã¾ã§å¾ æ©ãã¦ãããã¨ããä½ãã«ãªã£ã¦ããããã ãããã§ãã¢ããªã±ã¼ã·ã§ã³ãéåæå¦çãå¼ã³åºãã¿ã¤ãã³ã°ã«é¢ãããã«å¾ æ©ãããã¨ãã§ãããããããã¨ãä»åº¦ã¯éåæå¦çãå®äºãã¦ãå¾ æ©ãçµäºããªããã¨ããç¶æ ã«ãªãã
- éåæå¦çãå®äºãã¦ã io_service::work ã«ãã£ã¦ãã¤ã¾ã§ãã£ã¦ãçµäºããªãã³ã¼ã
#define _WIN32_WINDOWS 0x0400 #define _WIN32_WINNT 0x400 #include <iostream> #include <boost/array.hpp> #include <asio.hpp> using asio::ip::tcp; void on_resolve( const asio::error_code& error, tcp::resolver::iterator endpoint_iterator ) { if ( ! error ) { tcp::resolver::iterator end; while ( endpoint_iterator != end ) { tcp::endpoint endpoint = endpoint_iterator->endpoint(); std::cout << " capacity: " << endpoint_iterator->endpoint().capacity() << std::endl; std::cout << " data : " << endpoint_iterator->endpoint().data() << std::endl; std::cout << " port : " << endpoint_iterator->endpoint().port() << std::endl; std::cout << " size : " << endpoint_iterator->endpoint().size() << std::endl; // print address info. asio::ip::address address = endpoint.address(); std::cout << " address : " << address.to_string() << std::endl; std::cout << " is_v4 : " << address.is_v4() << std::endl; std::cout << " is_v6 : " << address.is_v6() << std::endl; std::cout << std::endl; endpoint_iterator++; } } else { std::cerr << error.message() << std::endl; } } int main( int argc, char* argv[] ) { try { if ( argc != 3 ) { std::cerr << "Usage: resolver <host> <service>" << std::endl; return 1; } asio::io_service io_service; asio::io_service::work work( io_service ); tcp::resolver resolver( io_service ); tcp::resolver::query query( argv[1], argv[2] ); // print query info. std::cout << query.host_name() << std::endl; std::cout << query.service_name() << std::endl; std::cout << std::endl; // start to resolve. resolver.async_resolve( query, on_resolve ); io_service.run(); } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; } return 0; }
ããã«å¯¾å¦ããã«ã¯ã¢ããªã±ã¼ã·ã§ã³ãçµäºãæãã ã¿ã¤ãã³ã°ã§ io_service::work ãç ´æ£ããå¿ è¦ãããã
- 10 ç§å¾ã«ã¦ã¼ã¶ãã¢ããªã±ã¼ã·ã§ã³ã®çµäºãæãã ã¨ä»®å®ãã¦çµäºããã³ã¼ã
#define _WIN32_WINDOWS 0x0400 #define _WIN32_WINNT 0x400 #include <iostream> #include <boost/array.hpp> #include <boost/bind.hpp> #include <boost/thread.hpp> #include <asio.hpp> using asio::ip::tcp; void on_resolve( const asio::error_code& error, tcp::resolver::iterator endpoint_iterator ) { if ( ! error ) { tcp::resolver::iterator end; while ( endpoint_iterator != end ) { tcp::endpoint endpoint = endpoint_iterator->endpoint(); std::cout << " capacity: " << endpoint_iterator->endpoint().capacity() << std::endl; std::cout << " data : " << endpoint_iterator->endpoint().data() << std::endl; std::cout << " port : " << endpoint_iterator->endpoint().port() << std::endl; std::cout << " size : " << endpoint_iterator->endpoint().size() << std::endl; // print address info. asio::ip::address address = endpoint.address(); std::cout << " address : " << address.to_string() << std::endl; std::cout << " is_v4 : " << address.is_v4() << std::endl; std::cout << " is_v6 : " << address.is_v6() << std::endl; std::cout << std::endl; endpoint_iterator++; } } else { std::cerr << error.message() << std::endl; } } void app_thread( std::auto_ptr<asio::io_service::work>& work ) { Sleep( 10 * 1000 ); work.reset(); } int main( int argc, char* argv[] ) { try { if ( argc != 3 ) { std::cerr << "Usage: resolver <host> <service>" << std::endl; return 1; } asio::io_service io_service; std::auto_ptr<asio::io_service::work> work( new asio::io_service::work( io_service ) ); // run application thread. boost::thread t( boost::bind( app_thread, boost::ref( work ) ) ); tcp::resolver resolver( io_service ); tcp::resolver::query query( argv[1], argv[2] ); // print query info. std::cout << query.host_name() << std::endl; std::cout << query.service_name() << std::endl; std::cout << std::endl; // start to resolve. resolver.async_resolve( query, on_resolve ); io_service.run(); t.join(); } catch ( std::exception& e ) { std::cerr << e.what() << std::endl; } return 0; }
ããã¾ã§ç解ã§ããããéä¸ã§ã¦ã¼ã¶ãçµäºãæãã ã¨ãã«éããã«çµäºãããã¨ãã§ããã³ã¼ããæ¸ããã¨ãã§ãããä¸ã®ãµã³ãã«ã³ã¼ãã§ã¯ãasio 以å¤ã« boost::threadãboost::bindãstd::auto_ptr ãªã©ãç»å ´ãã¦ããããasio ã§ãã¾ãã³ã¼ããæ¸ãã«ã¯ã©ããæ¬ ãããã¨ã®ã§ããªããã®ã ï¼ä½¿ããªãã¦ãã§ãããå°é£ã極ããã ããï¼ã
ãªããä»ã«ã io_service::run ã®ã¤ãã³ãã«ã¼ããæ¢ããæ¹æ³ã¯ããã¤ãããããã¨ãã°ãio_service::stop ã¨ãããã®ãããããããã¯ã¤ãã³ãã«ã¼ãã«çµäºä¾é ¼ãããã ãã§ãå¾ æ©å¦çã¯å«ã¾ãã¦ããªããããã¯è±èªããã¾ãç解ã§ããªãã¦ãã³ã¼ããè¦ã¦ãæããã§ãããWindows ã®å ´å以ä¸ã«è¦ã«ãªã£ã¦ããã
// Stop the event processing loop. void stop() { if (::InterlockedExchange(&stopped_, 1) == 0) { if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0)) { DWORD last_error = ::GetLastError(); asio::system_error e( asio::error_code(last_error, asio::error::get_system_category()), "pqcs"); boost::throw_exception(e); } } }
ã¡ãªã¿ã«ãio_service::reset ã¨ãããã®ãããããããã¯ã¤ãã³ãã«ã¼ããæ¢ããã¨ããç®çã§ä½¿ã£ã¦ã¯ãªããªããããã¥ã¡ã³ãã«ã¯ä»¥ä¸ã®ããã«ããã
This function must not be called while there are any unfinished calls to the run(), run_one(), poll() or poll_one() functions.
ãã®é¢æ°ã¯ãrun()ãrun_one()ãpoll()ãpoll_one() ã¨ãã£ãé¢æ°ã®å¼ã³åºããå®äºãã¦ããªãå ´åã¯å¼ã³åºãã¦ã¯ããã¾ããã
ã¨ããããã§ãã¤ãã³ãã«ã¼ãã®çµäºãã¢ããªã±ã¼ã·ã§ã³ããè¦æ±ããå ´åã«ã¯ãio_service::work ãç¨ããã¹ãã ã¨èãããããã¯å¼·å¶ããã¦ããããã§ã¯ãªãããäºå®ä¸ã®æ¨æºã¨ã¿ãªãããããã使ããã¨ã§ãã¤ãã³ãã«ã¼ãã®çµäºæ¡ä»¶ã容æãã¤å®å ¨ã«è¤æ°åã«ãããã¨ãã§ããããªããããå®å ¨ãã¨ããã¨ãä¾ãã°ã¦ã¼ã¶ãã¢ããªã±ã¼ã·ã§ã³ã®Ããã¿ã³ãæ¼ãã¦ã¦ã£ã³ãã¦ãéããããã¨ããæ¡ä»¶ããã¤ãã³ãã«ã¼ããæ¢ããããã®æ±ºå®æ¡ä»¶ã«ãªããªããã¨ãããããã ãã¢ããªã±ã¼ã·ã§ã³ã«ãã£ã¦ã¯Ããã¿ã³ãæ¼ãããå¾ããµã¼ãã«ä½ããã®æ å ±ãéä¿¡ãã¦ããçµäºãããã¨ãããããªãã¨ãããããã®ãããªå ´åã«ã¯ãio_service::stop ãå¼ã³åºãã¦ãã¾ãã¨ãã®å¾ã®éåæå¦çãå®è¡ãããªããªã£ã¦ãã¾ããããã¯ã¾ããã ããã
ã§ã¯ãio_service::reset ã¯ãã¤ä½¿ãã¹ããªã®ãï¼ããã¯ãio_service ã®ã¤ã³ã¹ã¿ã³ã¹ã使ãåãã¦ä½åº¦ãã¤ãã³ãã«ã¼ããå®æ½ããããããªå ´åã ã
ã¤ã¾ããio_service::stop ã¯æ¬å½ã«éä¿¡ãä¸æããªããã°ãªããªãã¨ãã¯å¼ã°ãªãããã«ããã¹ãã ã¨æãï¼ããã¾ã§é·ã ã¨èªã£ã¦ãããªããããã«ãã¦ãæãããããã¨æãããæ¹ããã¿ã¾ããããã®éãã§ãï¼ã
以ä¸ãããã¾ã§è¿°ã¹ã¦ããå 容ã¯ãasio ã®ãªãã¡ã¬ã³ã¹ã«è©³ããè¨è¼ããã¦ããã
è£è¶³
ããã¾ã§è¦ã¦ãã¦ãããæ¸ãã°ããåãã¨ãããã¨ã¯ç解ã§ãã¦ãããªããããªãã®ããç解ã§ããªããã¨ããæ¹ãããã¨æãã¾ãã®ã§è£è¶³ãã¦ããã¾ããã¾ããio_service ã¨ã¯ä½ãªã®ããã¨ãããã¨ã§ããããã㯠I/O å®äºãã¼ãã使ã£ãã¤ãã³ãã«ã¼ããæä¾ãã¦ãããã¯ã©ã¹ã§ããio_service::work ã¯ãio_service ã¯ã©ã¹ãçµäºããæ¡ä»¶ãã¤ã³ã¹ã¿ã³ã¹ã®çæã»ç ´æ£ã¨ããå½¢ã§è¨è¿°ããããã®ã¯ã©ã¹ã§ããC++ ã¯ã¹ã³ã¼ãã«ãããªã½ã¼ã¹ç®¡çãã¨ã¦ãç¾ããæ¸ããè¨èªãªã®ã§ããããæ´»ãããã¦ãã¾ãã
å®éãio_service::work ã¯ã©ã¹ã«ã¯ããã¨ãã£ãæ©è½ãããã¾ããããªãã¡ã¬ã³ã¹ãè¦ã¦ãåºç¤ã¨ãªã io_service ãåå¾ã§ãã以å¤ã«ã¯ä½ãæ©è½ãããã¾ãããã³ã¼ããè¦ã¦ã¿ãã¨ãåºç¤ã¨ãªã io_service ã®ã¨ããã«ã¦ã³ã¿ã 1 å¢ããã¦ããã ãã§ããããã«ãããio_service 㯠io_service::work ããã¹ã¦ç ´æ£ãããã¾ã§ io_service::run ãå®äºããªããã¨ããå¦çãå®ç¾ãã¦ãã¾ãï¼ãã¡ããå
é¨ã§ã¯ç°å¸¸ãçºçããå ´åã io_service::stop ãå¼ã³åºãããå ´åã«ã¯å¦çãæããããã«ãªã£ã¦ãã¾ããï¼ã
ã¾ã¨ã
- io_service::work ã使ã£ã¦ io_service::run ãå®äºããã¿ã¤ãã³ã°ãå¶å¾¡ãã
- io_service ã®æ¯ãèããååã«ææ¡ãã
- io_service::stop ãå¼ã³åºãå¿ è¦ããããï¼
- io_service::reset ãå¼ã³åºãå¿ è¦ããããï¼
æãªããä»åã¯ãã¾ããã¾ã¨ããã«ãªã£ã¦ãã¾ããã
次åã«åãã¦
ããã¾ã§ asio ãçºãã¦ã¿ãã¨ããã¾ãããããã ãã¨æã£ã¦èªåãæã£ã¦ããã³ã¼ãã«ãé©ç¨ããããªã£ã¦ããããã ã¨æãã¾ããããããéåæå¦çãå®å®åä½ãããã®ã¯è³é£ã®æ¥ã§ããããã®åºç¤ã¨ãªãã©ã¤ãã©ãªãæä¾ããã®ã¯å°é£ã極ããã¯ãã§ããã¤ã¾ããasio ã¯å©ç¨ã§ããã»ã©ã«å®å®ãã¦ããã®ãï¼ãã¨ãããã¨ãä½ããã確èªããªããã°ããã¾ããã次åã¯ãasio ã®ä¿¡é ¼æ§ãasio ã§ã§ããªããã¨ã«ã¤ãã¦ã§ããéãæ¤è¨ãã¦ã¿ã¾ãã