我用 c++ 和 libev 编写多线程服务器并且有一个问题。我在主线程中启动 default_loop,并在每个从线程中创建并启动 dynamic_loop。当我处理信号以停止进程时,我调用 break_loop(ev::ALL)。在默认事件循环停止但所有动态循环工作之后,需要帮助来停止动态循环。
环境:操作系统:Opensuse 13.1
编译器:g++ (SUSE Linux) 4.8.1 20130909
自由:4.15
资源:
#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 i = 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;
}
输出:
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
编译标志:-O0 -g -std=c++11
链接器标志:-lev
UPD,带有炒锅代码的源代码:
#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 i = 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;
}