记录下一个因为静态变量中使用了条件变量导致主线程无法退出的问题。
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
class AppAgent
{
private:
/* data */
public:
AppAgent() = default;
~AppAgent() {
std::cout << "destruct appagent" << std::endl;
// 解决方法2:
// 在这里通知下条件变量,确保没有等待,能够正常执行析构
// 参考: http://www.cplusplus.com/reference/condition_variable/condition_variable/~condition_variable/
// condition_.notify_all();
};
static AppAgent &GetInstance()
{
static AppAgent instance;
return instance;
}
void Init()
{
std::cout << "init" << std::endl;
}
int WaitForPubWork()
{
new_msg_ = false;
std::unique_lock<std::mutex> lck(mtx_);
while (!new_msg_)
{
condition_.wait(lck);
std::cout << "hh" << std::endl;
new_msg_ = true;
}
std::cout << "iii" << std::endl;
new_msg_ = false;
}
private:
bool new_msg_;
std::condition_variable condition_;
std::mutex mtx_;
};
void dotask()
{
AppAgent::GetInstance().Init();
while (1)
{
AppAgent::GetInstance().WaitForPubWork();
}
}
int main()
{
// 问题: 进程无法主动退出, 即便是子线程被detach
std::thread t1(dotask);
t1.detach();
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "exit main" << std::endl;
// 解决方法1: 可以使用quick_exit(0),不执行析构,快速退出。
// quick_exit(0);
return 0;
}
涉及到的问题点:
- 静态变量的析构顺序,是在main主线程退出之后才进行的
- 条件变量的析构正常执行的条件,是没有等待的场景,也就是说,析构前,需要提前唤醒一下
参考资料:
Google C++编程规范 – 第二十八条 -《静态变量和全局变量》
C++构造与析构(18) - 静态对象(static object)何时销毁
http://www.cplusplus.com/reference/condition_variable/condition_variable/~condition_variable/
网友评论