WebServer异步日志模块,Log类构析导致线程死锁解决分析

本文介绍了在C++中遇到的线程死锁问题,具体表现为日志系统在清理时卡住。通过调试发现是由于主线程在析构条件变量时,工作线程仍处于wait状态导致。尝试使用条件变量广播未解决问题。最终解决方案是在日志类析构时向阻塞队列添加特殊信号,唤醒工作线程并确保其能正常退出,同时保持内存无泄漏。

测试异步日志发现程序一直卡着,调了半天才发现感觉可能是线程死锁了,gdb查了两个线程bt果然是,主线程调用delete m_queue时要构析条件变量, 然而另一个线程已经用条件变量wait拿到互斥锁阻塞自己没法退出,导致主线程得一直等待。

把~Log的delete m_queue一行删除就解决了,但想尝试做到既能内存0泄露又能正常退出程序, 问题是不知道怎么解决工作线程的wait状态。

一开始以为在~block_queue部分加入m_cond.broadcast()就能解除工作线程wait状态了,毕竟是主程序调用的~block_queue, 然而不知道为何仍旧死锁。

热心的群友们有何良方吗?

log.h

#ifndef LOG_H
#define LOG_H
#include<iostream>
#include<string>
#include<cstring>
#include<stdarg.h>
#include<time.h>
#include<sys/time.h>
#include<queue>
#include<assert.h>

#include "../lock/locker.h"
#include "../log/block_queue.h"

using namespace std;
class Log{
    public:
        Log();
        ~Log();
        void init(const char *file_path, int log_buf_size = 8192, int max_line = 80000, int queue_size = 800);
        static Log* get_instance(){
            static Log instance;
            return &instance;
        }
        static void* async_write_thread(void *args){
            Log::get_instance()->async_write_log();
            return 0;
        };
        void write_log(int level, const char *format,...);
        void flush() {
            m_mutex.lock();
            fflush(m_fp);
            m_mutex.unlock();
        };
    private:
        char *get_current_time(char *time_buf, const char *format);
        void async_write_log(){
            string logstr;
            while(m_is_async &&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值