1、析構函數中,不能執行QEventLoop,會造成
- 重入問題:事件循環可能觸發其他事件,導致已析構的對象被再次訪問
- 信號槽連接:正在析構的對象可能還有未斷開的信號槽連接
- 未定義行為:對象狀態不確定,可能導致崩潰
2、當被刪除的對象執行過moveToThread操作的時候,不能用delete,需要用deleteLater。但是被刪除對象的子對象在它的析構函數里可以用delete
3、只要是start過的線程,在析構函數里都需要執行下面的代碼,保證線程關閉,否則程序會崩潰報錯
if (thread.isRunning()) { thread.quit(); if (!thread.wait(500)) { thread.terminate(); thread.wait(); LOG_ERROR("{}線程強制終止", thread.objectName()); } LOG_INFO("{}線程已停止", thread.objectName()); }
4、下面是我整理的幾個宏:
宏 | 說明 |
---|---|
DELETE_PTR_FUNC | 不跨線程的刪除調用的 |
DELETELATER_PTR_FUNC | 跨線程的刪除調用 |
STOP_OBJ_THREAD | 停止線程使用 |
#include <QThread>#define DELETE_PTR_FUNC(obj_ptr) \if (obj_ptr) \{ \obj_ptr->disconnect(); \delete obj_ptr; \obj_ptr = nullptr; \}#define DELETELATER_PTR_FUNC(obj_ptr) \if (obj_ptr) \{ \obj_ptr->disconnect(); \obj_ptr->deleteLater(); \obj_ptr = nullptr; \}#define STOP_OBJ_THREAD(thread) \if (thread.isRunning()) \{ \LOG_ERROR("{} thread stopping", thread.objectName()); \thread.quit(); \if (!thread.wait(200)) \{ \LOG_ERROR("{} thread did not quit gracefully, terminating", thread.objectName()); \thread.terminate(); \thread.wait(); \} \LOG_INFO("{} thread stopped", thread.objectName()); \}#define STOP_PTR_THREAD(thread_ptr) \if (thread_ptr && thread_ptr->isRunning()) \{ \LOG_ERROR("{} thread stopping", thread_ptr->objectName()); \thread_ptr->quit(); \if (!thread_ptr->wait(200)) \{ \LOG_ERROR("{} thread did not quit gracefully, terminating", thread_ptr->objectName()); \thread_ptr->terminate(); \thread_ptr->wait(); \} \LOG_INFO("{} thread stopped", thread_ptr->objectName()); \}