使用互斥和condition_variables

using mutexes and condition_variables

本文关键字:condition variables      更新时间:2023-10-16

我正在使用boost进程间库寻找两个线程之间正确的互连模式。我不认为这个库与使用标准库的典型并行编程不同。因此,我正在寻找一个基本的技术和理解这些同步原语的使用。

有两个线程:编写器和读取器,它们使用共享内存。用于同步访问共享内存中的对象(字符串和向量)的命名互斥对象。当读写器将数据写入共享内存时,用于等待的条件变量。因此,情况是:-读取器启动并初始化命名互斥体上的条件变量,条件是包含数据的向量应为非空。然后等待。。。-写入程序锁定互斥对象并填充向量-写入程序"通知一个"对数据向量的写入已完成,并解锁互斥对象-读取器接收到一个通知,锁定互斥对象并处理向量中的数据。

之后,读取器应该通知写入器读取已经完成,并且可以用新的数据部分再次填充向量。

所以我不知道如何正确设置所有这些等待和通知。看起来我的版本出现了死锁。请告知。

阅读器线程代码

    namespace bi = boost::interprocess;
    using bi_char_vector = bi::vector<char, CharAllocator>;
    bi::named_mutex             mtx{bi::open_or_create, "mtx"};
    bi::named_condition         cnd{bi::open_or_create, "cnd"};
    data = segment.find_or_construct<bi_char_vector>("data")(segment.get_segment_manager());
    while (!done) {
       bi::scoped_lock<bi::named_mutex> lock{mtx};
       cnd.wait(lock, [data] {return !data->empty(); });
       // process the data...
       cnd.notify_one();
    }

作者的线程代码:

    bi::managed_shared_memory segment(bi::open_only, shm_name.c_str());
    bi::named_mutex mtx{bi::open_only, "mtx"};
    bi::named_condition cnd(bi::open_only, "cnd");
    data = segment.find_or_construct<bi_char_vector>("data")(segment.get_segment_manager());
    for(std::size_t chunk_num = 0; chunk_num < chunk_count; ++chunk_num) {
        bi::scoped_lock<bi::named_mutex> lock { mtx };
        cnd.wait(lock);
        data->clear();
        // fills the data
        cnd.notify_one();
    }
}

如果我设置等待写入程序循环,它会停止,如果我删除了这个等待,看起来阅读器只接收和处理最后一次循环迭代

发现问题。在读者一侧添加:

while (!done) {
   bi::scoped_lock<bi::named_mutex> lock{mtx};
   cnd.wait(lock, [data] {return !data->empty(); });
   // process the data...
   data->clear();
   cnd.notify_one();
}

在写入方:

    for(std::size_t chunk_num = 0; chunk_num < chunk_count; ++chunk_num) {
        bi::scoped_lock<bi::named_mutex> lock { mtx };
        cnd.wait(lock, [data] {return data->empty(); });
        //...
        cnd.notify_one();
    }

现在它按预期工作