【发布时间】:2021-09-23 03:26:56
【问题描述】:
假设我有 ID 为 1 到 n 的 n 进程。我有一个包含大量数据的文件,其中每个进程只会存储数据的不相交子集。我想只使用一个进程加载和处理文件,将生成的数据存储在通过 Boost.Interprocess 分配的共享内存中的数据结构中,然后允许任何(包括加载文件的进程)从数据中读取.
为此,我需要利用位于here 的一些Boost.Interprocess 同步结构来确保进程在加载数据之前不会尝试读取数据。但是,我在这部分苦苦挣扎,这可能是由于我在这方面缺乏经验。目前,我有process(1) 将文件加载到共享内存中,我需要一种方法来确保任何给定进程在加载完成之前都无法读取文件内容,即使读取可能在加载发生后任意长时间发生。
我想尝试使用 notify_all 调用组合使用互斥锁和条件变量,以便 process(1) 可以向其他进程发出信号,可以从共享内存数据中读取,但这似乎有一个问题是,process(1) 可能会在某些process(i) 甚至尝试wait 以指示条件变量可以读取数据之前发送notify_all 调用。
关于如何以可靠的方式解决此问题的任何想法?
编辑 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;
};
上面大致是我问这个问题时得到的,但我不太满意,因为如果在指定进程执行notify_all调用之后调用read_into方法,那么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;
};
不确定上述是否最优雅,但我相信它应该确保进程在完成加载之前无法访问存储在共享内存中的数据,无论它们是在指定进程之前还是之后到达互斥锁m指定进程已加载文件内容。如果有更优雅的方式,我想知道。
【问题讨论】:
标签: c++ boost process multiprocessing boost-interprocess