IPC через два разных исполняемых файла?

У меня следующая проблема, и я понимаю, что мне нужно использовать либо IPC через общую память, либо сетевые сокеты.

У меня есть один исполняемый файл (то есть отдельный .exe), скомпилированный с помощью VS2010, который откуда-то получает данные, и он должен сделать эти данные доступными для второго исполняемого файла.

boost::interprocess::managed_shared_memory managed_shm(
    boost::interprocess::open_or_create,
    "MyMemBlock",
    4000000);

Второй исполняемый файл скомпилирован с помощью VS2012 и должен получать эти данные (или извлекать их из памяти) и обрабатывать их.

// fails with a boost::interprocess::interprocess_exception
boost::interprocess::managed_shared_memory managed_shm(
    boost::interprocess::open_only,
    "MyMemBlock");

Все должно быть максимально быстро. Компиляция обоих исполняемых файлов с одной и той же версией Visual Studio не возможна, одна кодовая база компилируется только с VS2010, другая — только с VS2012/2013.

Однако моя первая попытка с boost::interprocess не сработала (второй процесс выдает boost::interprocess::interprocess_exception), и я не совсем понимаю, как именно разделяется память, или, точнее, как распределяется информация о памяти передается от одного процесса к другому. Как первый исполняемый файл заполняет информацию о блоке общей памяти? Это работает только для нескольких процессов внутри одного исполняемого файла? Не несколько .exe? Должна ли это быть одна и та же DLL-библиотека Boost, используемая обоими исполняемыми файлами? Является ли мой единственный вариант IPC через сокеты?


person Ela782    schedule 12.12.2013    source источник
comment
У вас все описание проблемы состоит из двух слов, не получилось. (Кстати, самая распространенная программа с разделяемой памятью состоит в том, что один процесс сохраняет обычный указатель в разделяемой памяти, а затем другой процесс пытается его разыменовать. Это легко сделать, не осознавая этого. Например, вы можете' не хранить std::string в разделяемой памяти, потому что это так.)   -  person David Schwartz    schedule 12.12.2013
comment
@DavidSchwartz Я упомянул во втором блоке кода, который выдает эта функция. Однако, чтобы увидеть это, вам пришлось сильно прокрутить вправо. Я обновил вопрос, чтобы сделать это более ясным. Однако мой главный вопрос заключается в том, может ли этот IPC с общей памятью работать с двумя разными исполняемыми файлами, которые скомпилированы с двумя разными DLL-библиотеками Boost. Потому что мой разум не может представить, как второй процесс мог найти память первого процесса. Все примеры, которые я могу найти, используют один исполняемый файл, который порождает два разных процесса.   -  person Ela782    schedule 12.12.2013
comment
Я думаю, что разные библиотеки Boost не должны иметь значения, но то, как ваши данные структурированы в общей памяти, определенно будет иметь значение. Вы не должны пытаться совместно использовать какие-либо двоичные структуры данных, а только простые сериализуемые данные или примитивные типы данных.   -  person πάντα ῥεῖ    schedule 13.12.2013
comment
Я думаю, они могут иметь значение. Это то, что я хотел бы узнать здесь. Приведенный выше код работает, если запускать одну строку друг за другом в одном и том же файле cpp, но не работает, если выполняется в двух разных исполняемых файлах. Я даже не пытаюсь поделиться какими-либо данными, я не могу получить доступ к общей памяти из второго исполняемого файла.   -  person Ela782    schedule 13.12.2013
comment
Оба приложения имеют права администратора? Если нет, попробуйте это!   -  person Till    schedule 13.12.2013
comment
На самом деле, я заставил его работать. Тилль, ты заставил меня задуматься - я пробовал оба с правами администратора, но это ничего не изменило. Но на самом деле одно приложение использовало Boost 1.53, а другое 1.55. Затем я попробовал 1.53 на обоих - бум, это сработало. Итак, на мой реальный вопрос я сам ответил тем фактом, что это работает: да, IPC работает не только в двух процессах в одном исполняемом файле, но и в двух разных исполняемых файлах, которые используют разные компиляторы, разные библиотеки, разные библиотеки DLL Boost, НО они должны использовать одну и ту же версию Boost!   -  person Ela782    schedule 13.12.2013
comment
Тот, кто считает, что внес наибольший вклад, может сформулировать ответ, если к завтрашнему дню ничего не будет, я опубликую его. Спасибо!   -  person Ela782    schedule 13.12.2013


Ответы (2)


IPC работает с двумя разными исполняемыми файлами. Два процесса, обращающихся к общей памяти, не нужно компилировать в один и тот же исполняемый файл. На самом деле, их можно скомпилировать с разными версиями Visual Studio и разными Boost DLL. Однако в обоих исполняемых файлах необходимо использовать одну и ту же версию boost.

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

person Ela782    schedule 13.12.2013

Вы можете попробовать родной Windows IPC. Их много, вы можете погуглить . Я рекомендую файлы с отображением памяти. Здесь также хорошая статья от MS

Это пример сценария непостоянного файла карты памяти.

1. Process A creates the memory-mapped file and writes a value to it.

2. Process B opens the memory-mapped file and writes a value to it.

3. Process C opens the memory-mapped file and writes a value to it.

4. Process A reads and displays the values from the memory-mapped file.

5. After Process A is finished with the memory-mapped file, the file is 
   immediately reclaimed by garbage collection.

Взято из здесь

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

person Boris Ivanov    schedule 12.12.2013
comment
Файлы с отображением памяти действительно являются довольно простым решением. - person Till; 13.12.2013
comment
Он должен быть кроссплатформенным. И я подозреваю, что это будет иметь ту же проблему, что и моя попытка с boost ipc: может ли он работать с двумя разными исполняемыми файлами, которые скомпилированы с двумя разными DLL-библиотеками / libc? - person Ela782; 13.12.2013
comment
Это не кроссплатформенность. Но вы можете попробовать Boost-файлы boost.org/ doc/libs/1_35_0/libs/iostreams/doc/classes/ - person Boris Ivanov; 13.12.2013
comment
Файлы с отображением памяти — это быстро и легко! Я рекомендую их. - person japreiss; 13.12.2013
comment
Спасибо за вашу помощь. Однако я немного неправильно понял: мой вопрос никогда не заключался в том, как сделать IPC и какие есть разные способы. Я знаком с этим. Все дело было в двух исполняемых файлах и разных DLL. Но вы дали мне несколько хороших ссылок и подсказок, тем не менее здесь, спасибо! - person Ela782; 13.12.2013