如何解决使用 Boost.Interprocess
假设我有 n
个进程,ID 为 1
到 n
。我有一个包含大量数据的文件,其中每个进程只会存储数据的不相交子集。我想使用一个进程加载和处理文件,将结果数据存储在共享内存中通过 Boost.Interprocess 分配的数据结构中,然后允许任何(包括加载文件的进程)从数据中读取.
为此,我需要利用位于 here 的一些 Boost.Interprocess 同步构造来确保进程在加载数据之前不会尝试读取数据。但是,我在这部分苦苦挣扎,这可能是由于我在这方面缺乏经验。目前,我已经 process(1)
将文件加载到共享内存中,我需要一种方法来确保任何给定进程在加载完成之前无法读取文件内容,即使读取可能在加载发生后任意长时间发生.
我想尝试使用 notify_all
调用组合使用互斥锁和条件变量,以便 process(1)
可以向其他进程发出信号,可以从共享内存数据中读取数据,但是这似乎有一个问题,因为 process(1)
可能会在某些 notify_all
甚至尝试 process(i)
之前发送一个 wait
调用让条件变量表示可以读取数据。
关于如何以可靠的方式解决这个问题的任何想法?
编辑 1
这是我试图澄清我的困境并更清楚地表达我的尝试。我有一些类,我使用 Boost.Interprocess 分配到共享内存空间,其形式类似于以下:
namespace bi = boost::interprocess;
class cache {
public:
cache() = default;
~cache() = default;
void set_process_id(std::size_t ID) { id = ID; }
void load_file(const std::string& filename) {
// designated process to load
// file has ID equal to 0
if( id == 0 ){
// lock using the mutex
bi::scoped_lock<bi::interprocess_mutex> lock(m);
// do work to process the file and
// place result in the data variable
// after processing file,notify all other
// processes that they can access the data
load_cond.notify_all();
}
}
void read_into(std::array<double,100>& data_out) {
{ // wait to read data until load is complete
// lock using the mutex
bi::scoped_lock<bi::interprocess_mutex> lock(m);
load_cond.wait(lock);
}
data_out = data;
}
private:
size_t id;
std::array<double,100> data;
bi::interprocess_mutex m;
bi::interprocess_condition load_cond;
};
以上是我提出问题时的大致情况,但我不太满意,因为如果在指定进程执行 read_into
调用后调用了 notify_all
方法,那么 {{ 1}} 会卡住。我今天早上刚刚做的似乎解决了这个难题的方法是将这个类更改为以下内容:
read_into
不确定以上是否最优雅,但我认为它应该确保进程在完成加载之前无法访问存储在共享内存中的数据,是否在指定进程之前到达互斥锁namespace bi = boost::interprocess;
class cache {
public:
cache():load_is_complete(false){}
~cache() = default;
void set_process_id(std::size_t ID) { id = ID; }
void load_file(const std::string& filename) {
// designated process to load
// file has ID equal to 0
if( id == 0 ){
// lock using the mutex
bi::scoped_lock<bi::interprocess_mutex> lock(m);
// do work to process the file and
// place result in the data variable
// after processing file,notify all other
// processes that they can access the data
load_is_complete = true;
load_cond.notify_all();
}
}
void read_into(std::array<double,100>& data_out) {
{ // wait to read data until load is complete
// lock using the mutex
bi::scoped_lock<bi::interprocess_mutex> lock(m);
if( not load_is_complete ){
load_cond.wait(lock);
}
}
data_out = data;
}
private:
size_t id;
std::array<double,100> data;
bool load_is_complete;
bi::interprocess_mutex m;
bi::interprocess_condition load_cond;
};
或在指定进程加载文件内容后。如果有更优雅的方式,我想知道。
解决方法
典型的方式是使用命名的进程间互斥。见例如Boris Schälings "Boost" Book 中的示例,可免费获取,也可在线获取:https://theboostcpplibraries.com/boost.interprocess-synchronization
如果您的段创建已经适当地同步,您可以在共享段内使用“未命名”进程间mutices,这通常更有效,并避免使用无关的同步原语污染系统命名空间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。