C++ 带Boost的进程间读写器锁
在解释如何使用Boost实现读写器锁时,这是一个很好的例子。它看起来相对简单,我真的很喜欢它,但它似乎也使用了一个未命名的锁,我需要一个进程间解决方案(不需要是可移植的,只能是Windows) 有没有办法让进程间C++ 带Boost的进程间读写器锁,c++,boost,boost-interprocess,C++,Boost,Boost Interprocess,在解释如何使用Boost实现读写器锁时,这是一个很好的例子。它看起来相对简单,我真的很喜欢它,但它似乎也使用了一个未命名的锁,我需要一个进程间解决方案(不需要是可移植的,只能是Windows) 有没有办法让进程间共享\u互斥体?我看到有一个锁,但我不能让它与其他锁一起工作 任何指点都很感激 [编辑] 与此同时,我遇到了一个几乎一针见血的问题。我有两个问题: 它没有显示完整的代码(我猜我需要使用命名的\u upgradable\u mutex,但我不太确定)和 我不喜欢修改后的“writer”的答
共享\u互斥体
?我看到有一个锁,但我不能让它与其他锁一起工作
任何指点都很感激
[编辑]
与此同时,我遇到了一个几乎一针见血的问题。我有两个问题:
命名的\u upgradable\u mutex
,但我不太确定)和欢迎评论或好的解决方案。Boost.Interprocess文档介绍了所谓的it支持,以及两种支持的可升级互斥类型:
- ,一种非递归、匿名可升级的互斥体,可放置在共享内存或内存映射文件中
- ,一个非递归的、命名为可升级的互斥体
#include <iostream>
#include <string>
#include <unistd.h>
#include <boost/scope_exit.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/interprocess/sync/upgradable_lock.hpp>
// http://stackoverflow.com/questions/12439099/interprocess-reader-writer-lock-with-boost/
#define SHARED_MEMORY_NAME "SO12439099-MySharedMemory"
struct shared_data {
private:
typedef boost::interprocess::interprocess_upgradable_mutex upgradable_mutex_type;
mutable upgradable_mutex_type mutex;
volatile int counter;
public:
shared_data()
: counter(0)
{
}
int count() const {
boost::interprocess::sharable_lock<upgradable_mutex_type> lock(mutex);
return counter;
}
void set_counter(int counter) {
boost::interprocess::scoped_lock<upgradable_mutex_type> lock(mutex);
this->counter = counter;
}
};
int main(int argc, char *argv[])
{
using namespace boost::interprocess;
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " WHICH" << std::endl;
return 1;
}
const std::string which = argv[1];
if (which == "parent") {
shared_memory_object::remove(SHARED_MEMORY_NAME);
shared_memory_object shm(create_only, SHARED_MEMORY_NAME, read_write);
BOOST_SCOPE_EXIT(argc) {
shared_memory_object::remove(SHARED_MEMORY_NAME);
} BOOST_SCOPE_EXIT_END;
shm.truncate(sizeof (shared_data));
// Map the whole shared memory into this process.
mapped_region region(shm, read_write);
// Construct the shared_data.
new (region.get_address()) shared_data;
// Go to sleep for a minute.
sleep(60);
return 0;
} else if (which == "reader_child") {
shared_memory_object shm(open_only, SHARED_MEMORY_NAME, read_write);
mapped_region region(shm, read_write);
shared_data& d = *static_cast<shared_data *>(region.get_address());
for (int i = 0; i < 100000; ++i) {
std::cout << "reader_child: " << d.count() << std::endl;
}
} else if (which == "writer_child") {
shared_memory_object shm(open_only, SHARED_MEMORY_NAME, read_write);
mapped_region region(shm, read_write);
shared_data& d = *static_cast<shared_data *>(region.get_address());
for (int i = 0; i < 100000; ++i) {
d.set_counter(i);
std::cout << "writer_child: " << i << std::endl;
}
}
}
(必须首先启动父级:/a.out父级
)
输出显示“reader\u child”和“writer\u child”行的交错(所有“reader\u child”行在第一行“writer\u child”后显示非零值),因此它似乎工作正常。谢谢!这个技巧对我来说是否消除了一些疑问,尽管它并不完全是我想要的。当计数器被锁保护时,为什么要使用volatile?@BryanFok:我使用
volatile
,因为在锁定进程间可升级的互斥锁时,我没有看到任何内存障碍保证。有三种实现:posix、windows和spin。如果使用posix或windows实现,我认为不需要volatile
,因为pthread_mutex_lock()/WaitForSingleObject()是在后台调用的。spin实现使用原子CAS操作,我认为有些架构中CAS没有内存屏障保证。请参阅,例如.Related:请注意,即使使用作用域锁定或共享锁定,也不能防止在程序崩溃时使进程间互斥锁处于锁定状态。我发现我需要编写一个实用程序来调用boost::interprocess::named_upgradable_mutex::remove(),以便在发生此类事件后清理互斥。在linux上,这似乎调用了shm_unlink(),尽管我不确定这就是它的全部功能。顺便说一句,您可以在/dev/shm/中看到您的命名锁。
#!/usr/bin/env sh
./a.out reader_child &
./a.out reader_child &
./a.out writer_child &
./a.out reader_child &
./a.out reader_child &