Source: http://blog.csdn.net/hbhhww/article/details/7604982
Note that, like deadline_timer and socket, io_service is used as the parameter of the constructor. That is, asynchronous operations on them will be associated with the iocp contained in io_service. This also means that the deadline_timer associated with the io_service must be analyzed before the io_service is parsed.
One deadline_timer only maintains one time-out period, and one deadline_timer does not maintain multiple timers at the same time.
void wait();void wait(boost::system::error_code & ec);
This is a synchronization wait function, for example:
Boost: ASIO: io_service IO;
Boost: ASIO: deadline_timer T (Io, boost: posix_time: seconds (5 ));
T. Wait ();
This function has nothing to do with io_service because it does not involve Asynchronization. The implementation of this function in Windows is just a simple sleep. Therefore, cancel does not exist.
If t's expire time has passed, T. Wait will return immediately.
For example, the following code:
boost::asio::io_service io; boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));t.wait(); t.wait();
The first T. Wait will wait for 5S to return, and the first 2nd T. Wait will return immediately.
The wait function itself does not have a parameter and does not have the usage of T. Wait (seconds (5.
You can specify the time when constructing deadline_timer.
basic_deadline_timer( boost::asio::io_service & io_service);basic_deadline_timer( boost::asio::io_service & io_service, const time_type & expiry_time);basic_deadline_timer( boost::asio::io_service & io_service, const duration_type & expiry_time);
Note the differences between the two. The following two methods are equivalent:
Boost: ASIO: deadline_timer T (Io, boost: posix_time: microsec_clock: universal_time () + boost: posix_time: seconds (5 ));
Boost: ASIO: deadline_timer T (Io, boost: posix_time: seconds (5 ));
The former is absolute time, and the latter is relative time.
In addition to specifying the time in the deadline_timer constructor, you can also use the following two functions to specify the time:
Expires_at, expires_from_now. The difference between the two functions is that the former parameter is absolute time, and the latter is relative time. For example:
Boost: ASIO: io_service IO;
Boost: ASIO: deadline_timer T (IO );
T. expires_from_now (boost: posix_time: seconds (5 ));
T. Wait ();
Note that in addition to setting the next time-out time, these two functions also have the effect of canceling all the previous asynchronous wait. For more information, see the detailed explanations of these two functions.
Template <
TypenameWaithandler>
Void async_wait (
Waithandler handler );
Void handler (
Const boost: System: error_code & error // result of operation.
);
Note that this error is very important, indicating whether the handler is executed because of timeout or because it is cancel.
In either of the two cases, handler is executed: timeout or cancel.
This also implies that handler will be executed unless Io. Stop is called. Even if it is cancel.
Cancel can be used to call cancel directly or expires_at and expires_from_now to reset the timeout value.
void handle_wait(const boost::system::error_code& error, boost::asio::deadline_timer& t,int& count){ if(!error) { std::cout<< count<<"\n"; if(count++<5) { t.expires_from_now(boost::posix_time::seconds(1)); t.async_wait(boost::bind(handle_wait,boost::asio::placeholders::error, boost::ref(t),boost::ref(count))); } }} int main(){ boost::asio::io_service io; boost::asio::deadline_timer t(io); size_t a = t.expires_from_now(boost::posix_time::seconds(1)); int count = 0; t.async_wait(boost::bind(handle_wait,boost::asio::placeholders::error, boost::ref(t),boost::ref(count))); io.run(); return 0;}
Deadline_timer's destructor does not do anything, so it will not cause the sent async_wait to be cancel.
STD: size_tCancel();
STD: size_tCancel(
Boost: System: error_code & EC );
This function will cause all handler of async_wait (handler) not returned to be called, and error_code is boost: ASIO: Error: operation_aborted. The returned value is the number of timers that are cancel.
time_type expires_at() const;std::size_t expires_at( const time_type & expiry_time);std::size_t expires_at( const time_type & expiry_time, boost::system::error_code & ec);
Duration_typeExpires_from_now() Const; STD: size_tExpires_from_now(Const duration_type & expiry_time); STD: size_tExpires_from_now(Const duration_type & expiry_time, boost: System: error_code & EC );The above two groups of functions are used to set a new timeout time and cancel all unfinished async_wait operations. Note that the return values of these two functions are the number of cancel operations.
Considering the following scenario, we have a workerthread that is calling io_work.run ();
At this time, the main thread sends an asynchronous call to workerthread, such as post (...), considering that io_work.run is likely to have a backlog of handlers not processed, or some handlers processing is very time-consuming, it is expected that it must be returned within 5s. You can:
Void handle_wait (const boost: System: error_code & error, bool & RET)
{
If (! Error) ret = false;
}
Void handle_func (
Boost: shared_ptr <boost: ASIO: deadline_timer> T,
Boost: shared_ptr <boost: ASIO: io_service> Io,
Int * V)
{
Boost: ASIO: io_service: Work (* IO );
If (t-> cancel ()> 0)
{
* V = 1;
}
}
Void func_delay_1_second ()
{
Boost: ASIO: io_service IO;
Boost: ASIO: deadline_timer T (Io, boost: posix_time: seconds (1 ));
T. Wait ();
}
Bool sync_func (Int & V, boost: ASIO: io_service & io_work)
{
Boost: shared_ptr <boost: ASIO: io_service> io (new boost: ASIO: io_service );
Boost: shared_ptr <boost: ASIO: deadline_timer> T (new boost: ASIO: deadline_timer (* IO ));
T-> expires_from_now (boost: posix_time: seconds (5 ));
Bool ret = true;
T-> async_wait (boost: BIND (handle_wait, boost: ASIO: placeholders: error, boost: ref (RET )));
Io_work.post (boost: BIND (handle_func, T, Io, & V ));
Io-> Run ();
Return ret;
}
Int main ()
{
Boost: ASIO: io_service io_work;
Auto_ptr <boost: ASIO: io_service: Work> Work (new boost: ASIO: io_service: Work (io_work ));
Boost: thread workthread (boost: BIND (& boost: ASIO: io_service: Run, & io_work ));
For (INT I = 0; I <3; ++ I) io_work.post (func_delay_1_second );
Int V = 0;
Bool ret = sync_func (v, io_work );
If (RET) printf ("V % d \ n", V );
Work. Reset ();
Workthread. Join ();
Return 0;
}
In the above Code, if handle_wait is first entered, it indicates that the timeout. In this case, set ret = false and then Io. run exits, indicating that the call fails. If handle_func is entered later, T-> cancel returns 0, and no operation is performed. Although V is released when I/O. Run exits, handle_func does not perform any operations, which does not cause any security problems. If handle_func first enters, first use work so that Io. Run Will not exit, then cancel timer, and set it. Then work destructor, Io. Run will exit. Note the following synchronization problem: If handle_wait is entered first and then handle_func is entered, T-> cancel in handle_func will return 0 to do nothing. If you enter
Handle_func, and then enter handle_wait. T-> cancel, or 0 is returned or 1 is returned. Io. Run Will not exit because work is used. Note that both T and IO here are shared_ptr; otherwise, Io is returned if handle_wait is returned first. run will immediately exit and analyze the structure. handle_func will use the suspended T and Io, which will lead to illegal operations. Note that the IO here must be shared_ptr. If boost: ASIO: io_service: Work (* IO); change to work (t-> get_ioservice ()); t is valid, and the io_service indexed by T is invalid, which also leads to invalid operations. Remember
Io_service usage principle: the io_service can be parsed only after the other objects of all indexes are parsed.
Note that, like deadline_timer and socket, io_service is used as the parameter of the constructor. That is, asynchronous operations on them will be associated with the iocp contained in io_service. This also means that the deadline_timer associated with the io_service must be analyzed before the io_service is parsed.
One deadline_timer only maintains one time-out period, and one deadline_timer does not maintain multiple timers at the same time.
void wait();void wait(boost::system::error_code & ec);
This is a synchronization wait function, for example:
Boost: ASIO: io_service IO;
Boost: ASIO: deadline_timer T (Io, boost: posix_time: seconds (5 ));
T. Wait ();
This function has nothing to do with io_service because it does not involve Asynchronization. The implementation of this function in Windows is just a simple sleep. Therefore, cancel does not exist.
If t's expire time has passed, T. Wait will return immediately.
For example, the following code:
boost::asio::io_service io; boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));t.wait(); t.wait();
The first T. Wait will wait for 5S to return, and the first 2nd T. Wait will return immediately.
The wait function itself does not have a parameter and does not have the usage of T. Wait (seconds (5.
You can specify the time when constructing deadline_timer.
basic_deadline_timer( boost::asio::io_service & io_service);basic_deadline_timer( boost::asio::io_service & io_service, const time_type & expiry_time);basic_deadline_timer( boost::asio::io_service & io_service, const duration_type & expiry_time);
Note the differences between the two. The following two methods are equivalent:
Boost: ASIO: deadline_timer T (Io, boost: posix_time: microsec_clock: universal_time () + boost: posix_time: seconds (5 ));
Boost: ASIO: deadline_timer T (Io, boost: posix_time: seconds (5 ));
The former is absolute time, and the latter is relative time.
In addition to specifying the time in the deadline_timer constructor, you can also use the following two functions to specify the time:
Expires_at, expires_from_now. The difference between the two functions is that the former parameter is absolute time, and the latter is relative time. For example:
Boost: ASIO: io_service IO;
Boost: ASIO: deadline_timer T (IO );
T. expires_from_now (boost: posix_time: seconds (5 ));
T. Wait ();
Note that in addition to setting the next time-out time, these two functions also have the effect of canceling all the previous asynchronous wait. For more information, see the detailed explanations of these two functions.
Template <
TypenameWaithandler>
Void async_wait (
Waithandler handler );
Void handler (
Const boost: System: error_code & error // result of operation.
);
Note that this error is very important, indicating whether the handler is executed because of timeout or because it is cancel.
In either of the two cases, handler is executed: timeout or cancel.
This also implies that handler will be executed unless Io. Stop is called. Even if it is cancel.
Cancel can be used to call cancel directly or expires_at and expires_from_now to reset the timeout value.
void handle_wait(const boost::system::error_code& error, boost::asio::deadline_timer& t,int& count){ if(!error) { std::cout<< count<<"\n"; if(count++<5) { t.expires_from_now(boost::posix_time::seconds(1)); t.async_wait(boost::bind(handle_wait,boost::asio::placeholders::error, boost::ref(t),boost::ref(count))); } }} int main(){ boost::asio::io_service io; boost::asio::deadline_timer t(io); size_t a = t.expires_from_now(boost::posix_time::seconds(1)); int count = 0; t.async_wait(boost::bind(handle_wait,boost::asio::placeholders::error, boost::ref(t),boost::ref(count))); io.run(); return 0;}
Deadline_timer's destructor does not do anything, so it will not cause the sent async_wait to be cancel.
STD: size_tCancel();
STD: size_tCancel(
Boost: System: error_code & EC );
This function will cause all handler of async_wait (handler) not returned to be called, and error_code is boost: ASIO: Error: operation_aborted. The returned value is the number of timers that are cancel.
time_type expires_at() const;std::size_t expires_at( const time_type & expiry_time);std::size_t expires_at( const time_type & expiry_time, boost::system::error_code & ec);
Duration_typeExpires_from_now() Const; STD: size_tExpires_from_now(Const duration_type & expiry_time); STD: size_tExpires_from_now(Const duration_type & expiry_time, boost: System: error_code & EC );The above two groups of functions are used to set a new timeout time and cancel all unfinished async_wait operations. Note that the return values of these two functions are the number of cancel operations.
Considering the following scenario, we have a workerthread that is calling io_work.run ();
At this time, the main thread sends an asynchronous call to workerthread, such as post (...), considering that io_work.run is likely to have a backlog of handlers not processed, or some handlers processing is very time-consuming, it is expected that it must be returned within 5s. You can:
Void handle_wait (const boost: System: error_code & error, bool & RET)
{
If (! Error) ret = false;
}
Void handle_func (
Boost: shared_ptr <boost: ASIO: deadline_timer> T,
Boost: shared_ptr <boost: ASIO: io_service> Io,
Int * V)
{
Boost: ASIO: io_service: Work (* IO );
If (t-> cancel ()> 0)
{
* V = 1;
}
}
Void func_delay_1_second ()
{
Boost: ASIO: io_service IO;
Boost: ASIO: deadline_timer T (Io, boost: posix_time: seconds (1 ));
T. Wait ();
}
Bool sync_func (Int & V, boost: ASIO: io_service & io_work)
{
Boost: shared_ptr <boost: ASIO: io_service> io (new boost: ASIO: io_service );
Boost: shared_ptr <boost: ASIO: deadline_timer> T (new boost: ASIO: deadline_timer (* IO ));
T-> expires_from_now (boost: posix_time: seconds (5 ));
Bool ret = true;
T-> async_wait (boost: BIND (handle_wait, boost: ASIO: placeholders: error, boost: ref (RET )));
Io_work.post (boost: BIND (handle_func, T, Io, & V ));
Io-> Run ();
Return ret;
}
Int main ()
{
Boost: ASIO: io_service io_work;
Auto_ptr <boost: ASIO: io_service: Work> Work (new boost: ASIO: io_service: Work (io_work ));
Boost: thread workthread (boost: BIND (& boost: ASIO: io_service: Run, & io_work ));
For (INT I = 0; I <3; ++ I) io_work.post (func_delay_1_second );
Int V = 0;
Bool ret = sync_func (v, io_work );
If (RET) printf ("V % d \ n", V );
Work. Reset ();
Workthread. Join ();
Return 0;
}
In the above Code, if handle_wait is first entered, it indicates that the timeout. In this case, set ret = false and then Io. run exits, indicating that the call fails. If handle_func is entered later, T-> cancel returns 0, and no operation is performed. Although V is released when I/O. Run exits, handle_func does not perform any operations, which does not cause any security problems. If handle_func first enters, first use work so that Io. Run Will not exit, then cancel timer, and set it. Then work destructor, Io. Run will exit. Note the following synchronization problem: If handle_wait is entered first and then handle_func is entered, T-> cancel in handle_func will return 0 to do nothing. If you enter
Handle_func, and then enter handle_wait. T-> cancel, or 0 is returned or 1 is returned. Io. Run Will not exit because work is used. Note that both T and IO here are shared_ptr; otherwise, Io is returned if handle_wait is returned first. run will immediately exit and analyze the structure. handle_func will use the suspended T and Io, which will lead to illegal operations. Note that the IO here must be shared_ptr. If boost: ASIO: io_service: Work (* IO); change to work (t-> get_ioservice ()); t is valid, and the io_service indexed by T is invalid, which also leads to invalid operations. Remember
Io_service usage principle: the io_service can be parsed only after the other objects of all indexes are parsed.