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:锁定保护
/唯一锁定
选项是合适的。重新锁定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);