[Cppcms-users] Threads in async apps disappear if program is daemonized
Brought to you by:
artyom-beilis
|
From: CN <cn...@fa...> - 2013-12-20 09:02:06
|
I seem to be hitting the problem as pointed out here: http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them The strange effects happen to asynchronous application and the program is configured to be daemonized. config.js: "daemon":{ "enable":true } According to log, threads launched by asynchronous applications seem to simply disappear when the program is being daemonized. Further, the following two sets of code yield different behaviors. You may comment out either one and run this program to see the different log: Code set (a) cppcms::service s(argc,argv); booster::intrusive_ptr<async_app> async_app_=new async_app(s); s.applications_pool().mount(async_app_,cppcms::mount_point("^/async_app/(.+)",1)); s.run(); Code set (b) cppcms::service s(argc,argv); s.applications_pool().mount(new async_app(s),cppcms::mount_point("^/async_app/(.+)",1)); s.run(); Note: I use boost::thread instead of booster::thread (which does not support interrupt()), and call boost::thread::interrupt(); boost::thread_pointer::join(); in destructor in order to ensure all threads gracefully exit after the program is killed with signal SIGTERM. Comments will be appreciated! Regards, CN //============================== #include <iostream> #include <cstring> #include <cppcms/service.h> #include <cppcms/applications_pool.h> #include <cppcms/mount_point.h> #include <cppcms/rpc_json.h> #include <boost/thread/thread.hpp> #include <booster/log.h> #include <signal.h> //sigaction, signal() //------------------------------ static bool got_signal=false; void signal_handler(int signal_number) { std::cerr << "signal caught. signal number=" << signal_number << std::endl; got_signal=true; } //------------------------------ class class_poll { public: ~class_poll(){ BOOSTER_DEBUG("class_poll destructor"); } void poll(){ //boost::this_thread::disable_interruption di; while(true){ BOOSTER_DEBUG("before sleep"); try{ //See comments in main()! boost::this_thread::sleep(boost::posix_time::seconds(3)); //inturruption point //sleep(3); } catch(boost::thread_interrupted const& ){ BOOSTER_DEBUG("boost::thread_interrupted is caught"); break; } BOOSTER_DEBUG("after sleep"); } } }; //------------------------------ class async_app : public cppcms::rpc::json_rpc_server { private: boost::shared_ptr<boost::thread> poll_thread_pointer; public: async_app(cppcms::service &s) : cppcms::rpc::json_rpc_server(s){ boost::shared_ptr<class_poll> p(new class_poll()); poll_thread_pointer.reset(new boost::thread(boost::bind(&class_poll::poll,p))); } ~async_app(){ BOOSTER_DEBUG("async_app destructor"); try{ poll_thread_pointer->interrupt(); poll_thread_pointer->join(); } catch(...){} } }; //------------------------------ int main(int argc,char ** argv) { struct sigaction actions; memset(&actions,0,sizeof(actions)); sigemptyset(&actions.sa_mask); actions.sa_flags=0; actions.sa_handler=signal_handler; int sig_result; if((sig_result=sigaction(SIGINT,&actions,NULL)) != 0){ std::cerr << "sigaction(SIGINT) failed: " << sig_result << std::endl; std::terminate(); } if((sig_result=sigaction(SIGTERM,&actions,NULL)) != 0){ std::cerr << "sigaction(SIGTERM) failed: " << sig_result << std::endl; std::terminate(); } if((sig_result=sigaction(SIGHUP,&actions,NULL)) != 0){ std::cerr << "sigaction(SIGHUP) failed: " << sig_result << std::endl; std::terminate(); } try{ cppcms::service s(argc,argv); //(1)The following two statements work with both C sleep() and boost::this_thread::sleep() running in another thread if NOT daemonized. //(2)The following two statements does NOT work with C sleep() or boost::this_thread::sleep() running in another thread if daemonized. booster::intrusive_ptr<async_app> async_app_=new async_app(s); s.applications_pool().mount(async_app_,cppcms::mount_point("^/async_app/(.+)",1)); //(3)Next statement works with C sleep() running in another thread irrespective of being daemonized or not. //(4)Next statement does NOT work with boost::thread::sleep() regardless of being daemonized or not. //s.applications_pool().mount(new async_app(s),cppcms::mount_point("^/async_app/(.+)",1)); s.run(); //Next statement never gets executed when killed! Why? std::cerr <<"after cppcms::service::run()"; } catch(std::exception const &e) { std::cerr<<e.what()<<std::endl; } return 0; } //============================== -- http://www.fastmail.fm - Accessible with your email software or over the web |