To make long story short, my code:
#include <iostream>
#include <map>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
namespace ba = boost::asio;
namespace bp = boost::posix_time;
typedef std::map<int, ba::deadline_timer*> timer_map;
timer_map g_timers;
boost::mutex g_timers_lock;
ba::io_service g_ios;
void on_timer(int id) {
{
boost::mutex::scoped_lock lock(g_timers_lock);
timer_map::iterator it = g_timers.find(id);
assert(it != g_timers.end());
g_timers.erase(id);
}
// std::cout << "delete timer " << id << std::endl;
}
int main(void) {
boost::thread trd(boost::bind(&ba::io_service::run, &g_ios));
trd.detach();
int count = 0;
for (;;) {
for (int i = 0; i < 100; i++) {
ba::deadline_timer* pt = new ba::deadline_timer(g_ios, bp::seconds(1));
pt->async_wait(boost::bind(&on_timer, count));
boost::mutex::scoped_lock lock(g_timers_lock);
g_timers.insert(std::make_pair(count++, pt));
}
usleep(20000);
}
return 0;
}
==================================
I know, I should lock the g_timers, but should I lock the g_ios?
I mean these lines:
ba::deadline_timer* pt = new ba::deadline_timer(g_ios, bp::seconds(1));
pt->async_wait(boost::bind(&on_timer, count));
Are thread safety? It reference the g_ios, and will it call g_ios.add_job(this_timer) ..etc.. ?
to directly answer your question, yes an instance of an
io_serviceis thread safe. This is described in the documentation.Though, it’s not obvious to me what you’re attempting to accomplish. As written, your example accomplishes nothing because the
io_servicehas no work to do when you invokeio_service::run()so it returns immediately. You ignored the return value, I suspect if you inspected it, it would be zero.Your use of mutexes is also questionable. In general, if you need access to a shared resource from within an asynchronous handler, prefer to use a strand instead of a mutex. This concept is discussed quite well in the Asio examples and documentation, as is the use of threads.