Межпроцессное чтение / запись блокировки с Boost

Эта тема это золото, когда речь заходит о том, как реализовать блокировки чтения / записи с помощью Boost. Это кажется относительно простым, и я действительно люблю это, но оно также использует неназванную блокировку, и мне нужно межпроцессное решение (не должно быть переносимым, может быть только для Windows).

Есть ли способ иметь межпроцессный shared_mutex? Я вижу, что есть named_mutex но я не могу заставить его работать shared_lock от других замков.

Любые указатели приветствуются.

[РЕДАКТИРОВАТЬ]

А пока я сталкивался эта тема который почти ударяет гвоздь по голове. У меня есть две проблемы:

  1. он не показывает полный код (я думаю, мне нужно использовать named_upgradable_mutex но я не совсем уверен) и
  2. Мне не нравится ответ для модифицированного «писателя», который использует не готовый класс, который выполняет разблокировку в деструкторе, а последовательность из 3 необработанных вызовов мьютекса.

Комментарии или хорошие решения все еще приветствуются.

7

Решение

Документация Boost.Interprocess описывает так называемые обновляемые мьютексы это поддерживает и обновляемые операции мьютекса для двух поддерживаемых обновляемых типов мьютекса:

РЕДАКТИРОВАТЬ: Я считаю, что это работает:

#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;
}
}
}

Я попробовал это на Mac с помощью следующего скрипта:

#!/usr/bin/env sh
./a.out reader_child &
./a.out reader_child &
./a.out writer_child &
./a.out reader_child &
./a.out reader_child &

(Вы должны сначала запустить родителя: ./a.out parent)

Вывод показал чередование строк «reader_child» и «writer_child» (со всеми строками «reader_child», показывающими ненулевое значение после первой строки «writer_child»), поэтому он, кажется, работает.

10

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]