C++ 增压条件。我做错了什么? boost::条件变量cond; mutexmut; void数据库::run() { boost::唯一锁定(mut); while(true) { while(查询\u queue.empty()) 等待(锁定); mysqlpp::Query*q=querys\u queue.front();//

C++ 增压条件。我做错了什么? boost::条件变量cond; mutexmut; void数据库::run() { boost::唯一锁定(mut); while(true) { while(查询\u queue.empty()) 等待(锁定); mysqlpp::Query*q=querys\u queue.front();//,c++,boost,conditional-statements,boost-thread,C++,Boost,Conditional Statements,Boost Thread,试试看 while(true) { boost::唯一锁定(mut); while(查询\u queue.empty()) 等待(锁定); 你的线程代码看起来不错。唯一的气味是混合了锁护和唯一的锁,但这没什么大不了的。但是,我99%肯定,你的代码不是在你说的地方崩溃的,而是在下一行-q->execute();。似乎数据库的调用者::execute()方法正在传递一个指向堆栈上分配的查询对象的指针,或者,如果它是动态分配的,则在函数完成后立即删除它。不过,稍后,您的线程将重试指向该已删除(已释放或

试试看

while(true)
{
boost::唯一锁定(mut);
while(查询\u queue.empty())
等待(锁定);

你的线程代码看起来不错。唯一的气味是混合了
锁护
唯一的锁
,但这没什么大不了的。但是,我99%肯定,你的代码不是在你说的地方崩溃的,而是在下一行-
q->execute();
。似乎
数据库的调用者::execute()
方法正在传递一个指向堆栈上分配的查询对象的指针,或者,如果它是动态分配的,则在函数完成后立即删除它。不过,稍后,您的线程将重试指向该已删除(已释放或已破坏)对象的指针对象并尝试执行它。另一种可能性是,NULL指针被传递到
数据库::execute()
,这将导致相同的结果。

顺便说一句,您应该为条件变量指定一个更具描述性的名称BTW2,是故意的吗,当函数q->execute()时,互斥锁仍然被锁定执行了吗?我看不出它有什么问题。错误可能在其他地方。我不知道Boost。线程有那么好,但是在一个函数中使用
锁定保护
,在另一个函数中使用
唯一锁定
是否正常?@wilx:
锁定保护
/
唯一锁定
选项是合适的。重新锁定没有意义de>mutex。这就是
condition::wait
for的意思。@Vlad:我认为aaa意味着将
boost::unique_lock lock(mut);
从函数范围移动到
while(true)
数据库中的作用域::运行
不添加另一个。@Eugen:没错,这将在
循环时在
的每一次交互中引入锁定/解锁。这是非常有害的。
lock\u guard
很好,如果他不必将lock对象传递给条件变量。尝试注释q->execute并删除q。根据有帮助。但当我删除了对查询队列的两个引用时,它起到了作用。@Vladimir:是否有其他东西可以不加锁定地访问
查询队列
呢?另外,在您的示例中,我看不到任何
删除q;
。如果您能提供一个崩溃的最小工作代码示例,这会有很大帮助。否则它总是在猜测。但问题肯定不在您目前提供的线程代码中。
boost::condition_variable cond;
boost::mutex mut;

void Database::run()
{
    boost::unique_lock<boost::mutex> lock(mut);

    while(true)
    {
        while(queries_queue.empty())
            cond.wait(lock);

        mysqlpp::Query* q = queries_queue.front(); // <<< CRASHES HERE <<<
        q->execute();
        queries_queue.pop_front();
    }
}

void Database::Execute(mysqlpp::Query* q)
{
    {
        boost::lock_guard<boost::mutex> lock(mut);
        queries_queue.push_back(q);
    }
    cond.notify_one();
}
while(true)
{
    boost::unique_lock<boost::mutex> lock(mut);
    while(queries_queue.empty())
        cond.wait(lock);