为什么我收到一个简单的提升生产者/消费者计划的锁定断言失败

Why am I receiving a lock assertion failure for a simple boost producer/consumer program?

本文关键字:生产者 计划 失败 断言 锁定 消费者 简单 一个 为什么      更新时间:2023-10-16

我正在努力使用单独的类、c++ 标准库 deques 和 Linux 上的提升线程来创建一个简单的线程生产者/消费者示例。我正在通过引用将共享缓冲区、锁和条件变量作为成员变量传递给我的类。线程启动正常,但由于锁断言错误,通常会随机崩溃。

main: ../nptl/pthread_mutex_lock.c:80: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.

这是我在 main 中启动线程的方式

std::deque<double> buf;
boost::condition_variable_any buf_has_space;
boost::condition_variable_any buf_has_data;
boost::mutex buf_lock;
boost::thread producerThread(load_func, &buf, &buf_has_space, &buf_has_data, &buf_lock);
boost::thread consumerThread(consume_func, &buf, &buf_has_space, &buf_has_data, &buf_lock);
producerThread.join();
consumerThread.join();

producerThreadconsumerThread初始化并运行myProducermyConsumer的实例。

来自myProducer的相关代码:

void myProducer::add_to_buffer(){
    //Main loop
    for (int i=0; i<100000; i++){
        boost::mutex::scoped_lock lock(*buffer_lock);
        while (buffer->size() == max_size){
            buffer_has_space->wait(*buffer_lock);
        }
        buffer->push_back(i);
        buffer_has_data->notify_one();
        buffer_lock -> unlock();
    }
    //Consumer will stop when it sees -1
    boost::mutex::scoped_lock lock(*buffer_lock);
    while (buffer->size() == max_size){
        buffer_has_space->wait(*buffer_lock);
    }
    buffer->push_back(-1.0);
    buffer_has_data->notify_one();
    buffer_lock -> unlock();
}

来自myConsumer的相关代码:

void myConsumer::load_from_buffer(){
    double current = 0;
    while (current != -1.0) {
        boost::mutex::scoped_lock lock(*buffer_lock);
        while (buffer->size() == 0){
            buffer_has_data->wait(*buffer_lock);
        }
        current = buffer->front();
        buffer->pop_front();
        buffer_has_space->notify_one();
        buffer_lock->unlock();
        std::cout << current <<"n";
    }
}

我看过这些问题:

pthread_mutex_lock.c:62: __pthread_mutex_lock:断言"互斥>__data.__所有者 == 0"失败

线程互斥断言错误

但是,在我的类被解构之前,程序崩溃了,并且每个锁都与同一线程中的解锁匹配。

如果您的锁由锁卫 (scoped_lock) 拥有,则手动操作锁是错误的。

如果必须在作用域结束之前操作锁,则可以在scoped_lock本身上执行此操作:

lock.unlock();  // instead of buffer_lock -> unlock();