2015-02-09 4 views
1

Я пытаюсь разделить структуру между процессами, используя interprocess в Boost.boost interprocess managed_mapped_file find failing

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

У меня возникают проблемы с поиском объектов.

У меня есть следующее заявление:

typedef boost::interprocess::basic_managed_mapped_file 
    < char, 
    boost::interprocess::rbtree_best_fit<boost::interprocess::null_mutex_family,boost::interprocess::offset_ptr<void>>, 
    boost::interprocess::flat_map_index> 
    my_mapped_file; 

В процессе А, я делаю:

m_managedMappedFile.reset(new my_mapped_file(bip::open_or_create, filename, filesize)); 
auto hdr = m_managedMappedFile->find_or_construct<Foo>(bip::unique_instance)(); 
auto x = m_managedMappedFile->find<Foo>(bip::unique_instance); 

, который работает, как я ожидал бы, то есть он находит объект. Теперь, в процессе B:

m_managedMappedFile.reset(new my_mapped_file(bip::open_only, filename)); 
    auto ret = m_managedMappedFile->find<Foo>(bip::unique_instance); 

По какой-то причине метод находки возвращает нуль в процессе B. Я понимаю, что я должен делать что-то бесшабашное, но не могу понять это.

Может ли кто-нибудь помочь?

+0

Как вы блокируете/синхронизируете? Потому что вам лучше знать, что вы делаете. Мне никогда не приходилось обойти блокировку на уровне 'managed_mapped_file' – sehe

+0

@sehe Если я не использовал нулевой мьютекс, я просто не мог заставить его работать; выполнение find_or_construct (unique_instance)() работает, но затем поиск (unique_instance) в другом процессе, он будет ждать ожидания мьютекса (в priv_generic_find), даже если процесс A завершился! –

+0

Что такое платформа, библиотеки/версии компилятора? – sehe

ответ

1

Вам не нужно обходить механизм блокировки по умолчанию bip::managed_mapped_file индексов.

Смотрите, если вы можете выполнить следующую команду с успехом:

#include <iostream> 
#include <boost/interprocess/managed_mapped_file.hpp> 

namespace bip = boost::interprocess; 

struct X { 
    int i; 
}; 

int main() 
{ 
    { 
     bip::managed_mapped_file f(bip::open_or_create, "/tmp/mmf.bin", 1ul << 20); 

     if (!f.find<X>(bip::unique_instance).first) { 
      auto xp = f.find_or_construct<X>(bip::unique_instance)(); 

      assert(xp); 
      xp->i = 42; 
     } 
    } 

    { 
     bip::managed_mapped_file f(bip::open_only, "/tmp/mmf.bin"); 
     auto xp = f.find<X>(bip::unique_instance).first; 

     if (xp) 
      std::cout << "value: " << xp->i++ << "\n"; 
    } 
} 

Это должно напечатать 42 на первом запуске (или после того, как файл был воссоздан), а также увеличение числа на каждом последующем цикле.

Я собираюсь взглянуть на реализации позади unique_instance_t* перегрузок менеджеров сегмента, но я подозреваю, что они не могут работать потому что политика мьютекс была обнулена. На данный момент это просто догадка.

Я бы остановился на том, почему вы не можете получить Interprocess managed_mapped_file, работающий по умолчанию, на вашей платформе &.

+1

Большое спасибо за вашу помощь. Я был в процессе получения для вас версий компилятора/библиотеки, и я понял, что мое основное приложение - 64 бит, а мое тестовое приложение - 32 бит - это было (понятно) запутывающим. Еще раз спасибо! –

+1

Это действительно имеет смысл, так как выглядит, как минимум [здесь] (https://svn.boost.org/trac/boost/ticket/10011), метод 'unique_instance_t' использует' typeid (T) .name () ', которые будут разными :) – sehe

+1

(На самом деле, удалите это. Совместное использование классов C++ для разных процессов с ABI будет просто неопределенным поведением. Я не думаю, что Boost Interprocess обнаруживает это и избегает его) – sehe

Смежные вопросы