我正在使用boost进程库寻找两个线程之间互连的正确模式。与使用标准库的典型并行编程不同,我不认为库有特定的东西。 所以我正在寻找一种基本技术并理解这些同步原语的使用。
有两个线程:编写器和阅读器,它们使用共享内存。用于同步的命名互斥锁访问共享内存中的对象(字符串和向量)。读取器将数据写入共享内存时用于等待的条件变量。所以场景是: - 读取器在命名的互斥锁上启动和初始化条件变量,条件是带有数据的向量应该是非空的。并等待...... - writer锁定互斥锁并填充向量 - 作家"通知一个"写入数据向量已完成并解锁互斥锁 - 阅读器收到通知,锁定互斥锁并处理向量中的数据。
之后,读者应该通知作者阅读已经完成,并且可以使用新的数据部分再次填充向量。
所以我不确定如何设置所有这些等待并正确通知。看起来我的版本陷入僵局。请指教。
读者的线程代码
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();
}
}
如果我在编写器循环中设置等待,它会在此停止, 如果我删除此等待,看起来像读者只接收并处理最后一次循环迭代
答案 0 :(得分:0)
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();
}
现在按预期工作