async processing issues
Having a tough time learning ASIO. I'm trying to have one thread constantly
listen for new file monitoring events (mthread) while another thread
processes one task at a time (wthread). Somehow I'm still losing events
that don't get placed on the task_queue and it would seem that once an
event is lost, the file_handler callback for the dir_monitor stops working
thereafter for good. So I'm having a few issues with my solution.
If I comment out the sleep() method below, then for some reason the first
two lines that have to do with the dir_monitor immediately after the while
loop quickly eat through all available memory and the program will soon
crash within a minute or two. Leaving the sleep in keeps things stable, or
maybe it just eats away so slowly I don't notice it.
Leaving sleep() in also has the problem of *I think* causing missed file
events. The f_handler() function posts tasks that I create within the
dir_monitor callback back to the main thread via the io_service.post(), but
if its asleep, will it be able to place objects on the main processes
task_queue? I think thats one point where I'm going wrong.
If anyone sees where I'm going wrong, any help much appreciated.
---
static queue
See my comments below.
// dir_monitor thread boost::thread mthread = boost::thread(boost::bind(&boost::asio::io_service::run, boost::ref(io_service)));
// setup work to prevent premature exit shared_ptrboost::asio::io_service::work work(new boost::asio::io_service::work(work_service));
Set "work" *before* running io_service, otherwise io_service::run might already have exited at this point, because it's out of work.
while (true) { io_service.reset();
I'm not sure what this loop is for, but why do you reset io_service? It will stop working. Please, read manual: http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/io_servic...
Heres another combination of many things I've been trying, but still cant get this to work. Unfortunately, this only works once, meaning it only receives one dir_monitor callback event, and if I cause another same event in a monitored directory, the f_handler() callback will no longer get called. I am able to post from thread1 to thread2 or from thread1 to the main process, but that also only works one time. Any ideas? --- boost::asio::io_service service1; boost::asio::io_service service2; // dir_monitor callback running in thread 1 void f_handler(const boost::system::error_code &ec, const boost::asio::dir_monitor_event &ev) { TaskObj tsk = new TaskObj(...); // detect event, create task and post functor to thread 2 which handles tasks service2.post(boost::bind(&TaskObj::do_it, tsk)); } int main(...) { boost::asio::dir_monitor dm(service1); for (/*directory list*/) { dm.add_directory(dir); } dm.async_monitor(f_handler); // setup work to prevent exit and before running io_service shared_ptrboost::asio::io_service::work work(new boost::asio::io_service::work(service)); // thread to constantly monitor dirs boost::thread t1 = boost::thread(boost::bind(&boost::asio::io_service::run, boost::ref(io_service))); t1.detach(); // thread to do tasks as posted by dir_monitor thread and idle if no tasks exists boost::thread t2(boost::bind(&boost::asio::io_service::run, boost::ref(work_service))); t2.detach(); while (true) { // do other stuff or idle, don't want main process to exit. }
Had some typos in the previous post, correcting ... --- boost::asio::io_service service1; boost::asio::io_service service2; // dir_monitor callback running in thread 1 void f_handler(const boost::system::error_code &ec, const boost::asio::dir_monitor_event &ev) { TaskObj tsk = new TaskObj(...); // detect event, create task and post functor to thread 2 which handles // tasks service2.post(boost::bind(&TaskObj::do_it, tsk)); } int main(...) { boost::asio::dir_monitor dm(service1); for (/*directory list*/) { dm.add_directory(dir); } dm.async_monitor(f_handler); // setup work to prevent exit and before running io_service shared_ptrboost::asio::io_service::work work(new boost::asio::io_service::work(service2)); // thread to constantly monitor dirs boost::thread t1 = boost::thread(boost::bind(&boost::asio::io_service::run, boost::ref(service1))); t1.detach(); // thread to do tasks as posted by dir_monitor thread and idle if no tasks exists boost::thread t2(boost::bind(&boost::asio::io_service::run, boost::ref(service2))); t2.detach(); while (true) { // do other stuff or idle, don't want main process to exit. }
boost::asio::io_service service1; boost::asio::io_service service2;
// dir_monitor callback running in thread 1 void f_handler(const boost::system::error_code &ec, const boost::asio::dir_monitor_event &ev) { TaskObj tsk = new TaskObj(...); // detect event, create task and post functor to thread 2 which handles // tasks
service2.post(boost::bind(&TaskObj::do_it, tsk)); }
int main(...) { boost::asio::dir_monitor dm(service1);
for (/*directory list*/) { dm.add_directory(dir); }
dm.async_monitor(f_handler);
// setup work to prevent exit and before running io_service shared_ptrboost::asio::io_service::work work(new boost::asio::io_service::work(service2));
// thread to constantly monitor dirs boost::thread t1 = boost::thread(boost::bind(&boost::asio::io_service::run, boost::ref(service1)));
First of all, I don't know how dir_monitor works (it's not a part of an official Boost.Asio). But if its interface semantic is consistent with other Asio interfaces, than async_monitor should asynchronously monitor 1 event. So, after async_monitor gets completed, service1 runs out of work and its run() loop exits (not that you didn't give it any "work" object).
participants (2)
-
Igor R
-
SRD