多线程编程:`std::bad_function_call` 异常分析与解决

66 阅读1分钟

多线程编程:std::bad_function_call 异常分析与解决

在一个简易线程池的创建过程中,发现程序有较大概率抛出std::bad_function_call异常。该异常通常发生在 std::function 对象为空状态时被调用 的情况下。

检查代码后发现,std::bad_function_call出现在线程创建后的任务函数函数运行前,线程函数未运行时就出现std::bad_function_call异常。

最后定位问题到线程类构造函数内,线程类会先运行run函数,在run函数内会进行swap操作拿到任务函数,但任务函数初始化在pthread_create后,导致run内的swap操作可能拿到空值引发std::bad_function_call异常。

//引发异常代码片段
Thread::Thread(std::function<void()> cb, const std::string& name = "UNKNOWN"){
    m_name = name;
    m_cb = cb;                 // 正确位置
    int rt = pthread_create(&m_thread, nullptr, &Thread::run, this);
    // m_cb = cb;              // 应放在pthread_create 前
    ...
}
...
void* Thread::run(void* args){
    Thread* thread = (Thread*) args;
    t_thread = thread;
    thread->m_id = m_sylar::getThreadId();
    pthread_setname_np (pthread_self(), thread->m_name.substr(0, 15).c_str());          
    std::function<void()> cb;
    cb.swap(thread->m_cb);       // 这里可能获得空值
    cb();
    return 0;
}