linux - Libev c++ can't stop dynamic loops in multithread application -


i write multithread server c++ , libev , has 1 problem. start default_loop in main thread , create , start dynamic_loop in every slave threads. when handle signals stop process call break_loop(ev::all). after default event loop stopped dynamic loops work, need stop dynamic loops.

environment: os: opensuse 13.1

compiler: g++ (suse linux) 4.8.1 20130909

libev: 4.15

source:

#include <vector> #include <memory> #include <ev++.h> #include <thread> #include <iostream>  class thread  { public:     typedef std::thread thread_t;     thread() {std::cout << "thread created" << std::endl;}     ~thread() {std::cout << "thread destructed" << std::endl;}     virtual void start() {this->thread = thread_t(&thread::run, this);}     virtual void stop()     {         std::cout << "unloop" << std::endl;         std::cout << this->thread.get_id() << std::endl;          if(this->thread.joinable())             std::cout << " it's joinable" << std::endl;          this->loop->break_loop(ev::all);          this->thread.join();         std::cout << "thread " << this->thread.get_id() << " stopped" << std::endl;     }      void run()     {         this->loop = new ev::dynamic_loop(ev::auto);          this->timer.set(*this->loop);         this->timer.set<thread, &thread::on_timer>(this);         this->timer.start(1, 1);          std::cout << "thread " << this->thread.get_id() << " started" << std::endl;          this->loop->run(0);          this->timer.stop();          std::cout << "thread " << this->thread.get_id() << " finalized" << std::endl;     }      void on_timer()     {         std::cout << "time event" << std::endl;     } protected:     thread_t thread;     ev::dynamic_loop *loop;     ev::timer timer; private:     thread(const thread &) = delete;     void operator=(const thread &) = delete; };  class server { public:     void run()     {         std::cout << "start server" << std::endl;          this->sigint.set<&server::on_terminate_signal>();         this->sigint.start(sigint);          this->sigterm.set<&server::on_terminate_signal>();         this->sigterm.start(sigterm);          this->sigkill.set<server::on_terminate_signal>();         this->sigkill.start(sigkill);          std::vector<thread*> threads;          for(auto = 0; i< 5; i++)         {             auto buf = new thread();             buf->start();             threads.push_back(buf);         }          this->loop.run(0);          this->sigint.stop();         this->sigterm.stop();         this->sigkill.stop();          for(auto *iter: threads)         {             iter->stop();             delete (&iter);         }          std::cout << "gracefull exit" << std::endl;     } protected:     ev::default_loop loop;     ev::sig sigint;     ev::sig sigkill;     ev::sig sigterm;      static void on_terminate_signal(ev::sig& signal, int)     {         signal.loop.break_loop(ev::all);         signal.stop();         std::cout << "signal handled" << std::endl;     }     };  int main(int, char**) {     std::cout << "libev " << ev::version_major() << "." << ev::version_minor() << std::endl;     server server;     server.run();      return 0; } 

output:

  libev 4.15     start server     thread created     thread created     thread created     thread created     thread created     thread 139639372617472 started     thread 139639326365440 started     thread 139639337928448 started     thread 139639361054464 started     thread 139639349491456 started     time event     time event     time event     time event     time event     time event     time event     time eventtime event      time event     time event     time event     time event     time event     time event     ^csignal handled     unloop     139639372617472      it's joinable     time eventtime event      time event     time event     time event     time event     time event     time event     time event      time event 

compilation flags: -o0 -g -std=c++11

linker flags: -lev

upd, source wok code:

    #include <vector>     #include <memory>     #include <ev++.h>     #include <thread>     #include <iostream>      class thread {     public:             typedef std::thread thread_t;             thread(): loop(ev::auto) {std::cout << "thread created" << std::endl;}             virtual ~thread() {std::cout << "thread destructed" << std::endl;}             virtual void start() {this->thread = thread_t(&thread::run, this);}             virtual void stop()             {                     std::cout << "try stopping " << this->thread.get_id() << std::endl;                      this->stopper.send();                     this->thread.join();             }              void run()             {                     this->timer.set(this->loop);                     this->timer.set<thread, &thread::on_timer>(this);                     this->timer.start(1, 1);                      this->stopper.set(this->loop);                     this->stopper.set<thread, &thread::on_stop>(this);                     this->stopper.start();                      std::cout << "thread " << this->thread.get_id() << " started" << std::endl;                      this->loop.run(0);                      std::cout << "thread " << this->thread.get_id() << " finalized" << std::endl;             }     protected:             thread_t thread;             ev::dynamic_loop loop;             ev::timer timer;             ev::async stopper;              void on_timer()             {                     std::cout << "time event" << std::endl;             }              void on_stop()             {                     std::cout << "on stop event " << std::endl;                      this->stopper.stop();                     this->timer.stop();                      this->loop.break_loop(ev::all);             }     private:             thread(const thread &) = delete;             void operator=(const thread &) = delete;     };      class server {     public:             void run()             {                     std::cout << "start server" << std::endl;                      this->sigint.set<&server::on_terminate_signal>();                     this->sigint.start(sigint);                      this->sigterm.set<&server::on_terminate_signal>();                     this->sigterm.start(sigterm);                      this->sigkill.set<server::on_terminate_signal>();                     this->sigkill.start(sigkill);                      std::vector<thread*> threads;                      for(auto = 0; i< 5; i++)                     {                             auto buf = new thread();                             buf->start();                             threads.push_back(buf);                     }                      this->loop.run(0);                      this->sigint.stop();                     this->sigterm.stop();                     this->sigkill.stop();                      (auto &iter: threads)                     {                             iter->stop();                             delete iter;                     }                      std::cout << "gracefull exit" << std::endl;             }     protected:             ev::default_loop loop;             ev::sig sigint;             ev::sig sigkill;             ev::sig sigterm;              static void on_terminate_signal(ev::sig& signal, int)             {                     signal.loop.break_loop(ev::all);                     signal.stop();                     std::cout << "signal handled" << std::endl;             }     };      int main(int, char**)     {             std::cout << "libev " << ev::version_major() << "." << ev::version_minor() << std::endl;             server server;             server.run();              return 0;     } 

answer

you need stop timer before stop loop, contains timer:

move line:

this->timer.stop();

before this:

this->loop->break_loop(ev::all);

dont play raw pointer

you can rid of pointer:

ev::dynamic_loop *loop;

this->loop = new ev::dynamic_loop(ev::auto);

and make class variable, initialized in constructor:

ev::dynamic_loop loop;

thread() : loop(ev::auto)

probably mistake

delete (&iter);

of course, if not want remove pointer pointer iter.


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -