Методы межпроцессного взаимодействия
Здравсте.
Вот собсна сабж. Кто какие знает и рекомендует? Желательно кроссплатформенное решение. Но если такого не существует, то тада для винды.
Пока думаю про пайпы, но это кажись чисто виндовое решение. К тому же пока не знаю, на сколько шустрое.
Еще мысли про маппед файлы, но проблема та же — кроссплатформенность.
У кого какой опыт и мысли?
#1
0:13, 21 июля 2009
Пайпы — самое простое, особенно в *nix. Хотя могут вести себя немного по разному в разных ОС. Ещё вариант — сокеты, их API почти везде один.
#2
0:18, 21 июля 2009
#3
0:21, 21 июля 2009
DeadMeat
> Еще мысли про маппед файлы, но проблема та же — кроссплатформенность.
WinApi — CreateFileMapping/OpenFileMapping
Linux — mmap
#4
1:33, 21 июля 2009
#5
3:38, 21 июля 2009
boost.interpocess
просто, доступно, быстро, кроссплатформенно
для быстрого старта там есть message_queue
под win платформу не рекомендую сокеты для нагруженного ipc протокола, лучше взять шареную память или пайпы (которые в конечном счёте та же шареная память)
#6
4:11, 21 июля 2009
oistalker
+1
#7
10:58, 21 июля 2009
JokerR
> под win платформу не рекомендую сокеты для нагруженного ipc протокола
#8
11:41, 21 июля 2009
Вот, мне помогло в свое время.
#9
11:47, 21 июля 2009
boost.interprocess создаёт временный файл на каждый блок данных передаваемый между программами. По крайней мере под виндой.
Кроме того что эти файлы потом остаются валяться на диске, это ещё и небезопасно если в них останутся валяться какие-то важные данные или пароли.
#10
19:12, 21 июля 2009
kvakvs
>boost.interprocess создаёт временный файл на каждый блок данных передаваемый между программами. По крайней мере под виндой.
>Кроме того что эти файлы потом остаются валяться на диске, это ещё и небезопасно если в них останутся валяться какие-то важные данные или пароли.
можно минимальный пример для воспроизведения (с файлом на каждый блок и неудаляемыми файлами)? я не наблюдал такого поведения (более того мне не понятна даже возможная причина для такого поведения).
pentagra
>JokerR
>> под win платформу не рекомендую сокеты для нагруженного ipc протокола
>а почему?
потому что на больших объёмах данных пайпы будут на порядок быстрее (видимо пакетам тяжело продираться сквозь сетевой стек, даже если ето loopback 127.0.0.1).
#11
19:21, 21 июля 2009
из того что пришло на ум:
1. пайпы (win и nix) — самое то, просто и удобно
2. сокеты (win и nix)
3. проецируемые файлы (win) либо расшаренная память (nix) — самое то тоже
4. почтовые слоты (win) — УГ
5. DDE (win) — древнее УГ
6. буфер обмена (win) — УГ
7. WM_COPYDATA (win) — УГ
#12
19:31, 21 июля 2009
JokerR
Мне надо было передавать между тредами блок данных, после ряда граблей решил попробовать Boost::interprocess, в таком стиле
managed_shared_memory segment //create segment name segment size ( create_only, "MySharedMemory", 65536); //. через время shared_memory_object::remove( "MySharedMemory");
После успешной обработки данных блоки точно удалялись, то есть ошибок не было и данные обрабатывались и вызывался sh_m_object::remove
Очевидно же что shared memory должна создать файл, хотя очень хотелось бы чтобы это был не файл а блок памяти 🙂
Через время я понял что это всё мне не нужно и от интерпроцесса избавился, а неприятный осадок остался.
#13
20:03, 21 июля 2009
Всем спасибо за советы.
Думаю останусь при маппед файлах. Сделаю обертку и все. Мне главное скорость, поэтому без всяких лишних проверок на доступ и т.п. Работать это будет на сервере поэтому все это исключается.
Еще раз спасибо.
#14
11:14, 22 июля 2009
JokerR
> > почему?
> потому что на больших объёмах данных пайпы будут на порядок быстрее (видимо
> пакетам тяжело продираться сквозь сетевой стек, даже если ето loopback
> 127.0.0.1).
и хочешь сказать, это только под виндой? меня смутило не то, что ты посоветовал пайпы вместо сокетов, а то, что сделал упор на то, что под виндой не рекомендуешь сокеты.
boost/interprocess как расшарить класс в памяти между процессами?
То, что разные процессы видят один и тот же сегмент shared memory по разным адресам, это как раз нормально. Поэтому использовать указатели, используемые другими процессами даже внутри этой области (не говоря уж о ссылках в обычную кучу), нельзя.
13 июн 2018 в 20:34
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Достаточно обычный #include , заменить на interprocess-овский.
#include
И саму переменную объявлять не std::string , a boost::interprocess::string .
И ребёнок видет то что видет родитель и может менять, и его изменения так же увидет родитель. Точно так же надо отдельный, собственный vector, map и т.д. брать не из std:: , а из бустов. Полный список всех портов.
#include #include #include // #include #include //std::system #include #include using namespace boost::interprocess; class MyClass < public: MyClass(); ~MyClass(); // std::string name; string name; >; MyClass::MyClass() < this->name = "init"; > MyClass::~MyClass() < >int main( int argc, char *argv[] ) < if ( argc == 1 ) < // Parent process // std::cout ~shm_remove() < shared_memory_object::remove("MySharedMemory"); >> remover; managed_shared_memory shm(create_only, "MySharedMemory", 1000); // Create a managed shared memory MyClass *myclass = shm.construct("MyClass")(); // Construct a named object std::cout name << std::endl; std::string s( argv[0] ); s += " child "; std::system( s.c_str() ); std::cout name name = "step 2"; std::system( s.c_str() ); > else < // std::cout << "child: " << std::endl; managed_shared_memory shm(open_only, "MySharedMemory"); MyClass *myclass = shm.find("MyClass").first; std::cout name name = "step 1"; > return 0; >
parent see: init child see: init parent see: step 1 child see: step 2
boost_interprocess — что это за папка и можно ли ее удалить?

Приветствую друзья! Сегодня я постараюсь выяснить — что это за папка boost_interprocess, зачем она нужна и можно ли удалить. Постараюсь все написать простыми словами.
boost_interprocess — что это такое?
Папка от софта, который использует в своей работе библиотеку Boost.Interprocess.
boost_interprocess можно заметить в C:\ProgramData\ .
Может появиться при наличии ПО Geforce Experience (фирменное ПО для видеокарт NVIDIA).
Причина появления — софт использует кроссплатформенную библиотеку Boost.Interprocess (C++), которая эмулирует разделяемую память с поведением как в POSIX, то есть создавая файлы на диске и отображая их в память. Эти файлы и создаются в папке boost_interprocess.
Сегодня при разработке GeForce уже используется язык C++. Поэтому все сходится.
Простыми словами — программисты пишут софт, но не все функции нужно создавать заново, иначе это будет долго. Многие функции уже созданы давно и протестированы. Чтобы их можно было использовать при разработке ПО на многих языках — существуют библиотеки, внутри которых уже присутствуют функции. Одна из таких библиотек и есть Boost.Interprocess, которая для своей корректной работы создает папку boost_interprocess. Ну а эту библиотеку уже может использовать разный софт.
Можно ли удалить boost_interprocess?
В принципе удалять не стоит — может повлиять на работу ПО, которое использует библиотеку Boost.Interprocess.
Если папка постоянно пустая — значит она используется для временных файлов, которые после использования — удаляются. Это нормальное явление, даже грамотное.
Однако если удалить очень хочется, тогда предлагаю вам такой план действий:
- Создаем точку восстановления на всякий случаем и даем название, например До переименования boost_interprocess. Советую не игнорировать этот пункт!
- Выполняем перезагрузку ПК. После перезагрузки никакие программы не запускаем. А все, которые запустились автоматически — выходим из них.
- Папку не удаляете, а переименовываете, при этом лучше сохранить оригинальное название, я предлагаю просто добавить символ нижнего пробела _. Если при переименовании будут проблемы — используйте утилиту Unlocker, она спецом чтобы переименовывать и удалять неудаляемые папки/файлы.
- После переименования — выполняем перезагрузку. Тестируем некоторое время, день-два или больше.
- При проблемах — возвращаем оригинальное название папки и делаем перезагрузку. Если это не помогает — используем ранее созданную точку восстановления.
- Если проблем не будет, можем сделать вывод: папка временная, ее можно удалить, но если размер ее маленький — пусть будет, ведь компьютера она точно не грузит.
Судя по этой картинке — boost_interprocess может быть даже заблокирована:

Заключение
- boost_interprocess — папка, создаваемая софтом, который использует в своей работе библиотеку Boost.Interprocess.
- Таким софтом может выступать фирменное ПО для видеокарты, материнской платы.
- Удалять не рекомендуется, только в случае когда занимает много места. Предварительно создав точку восстановления!
Работа с файлами в C++ с использованием Boost 11.11.2020 12:17

Привет! Я время от времени рассказываю на Хабре о решениях распространённых задач на C++, и вообще люблю делиться опытом. Поэтому даже написал целую книгу, которая называется «Разработка приложений на С++ с использованием Boost». Она может быть интересна разработчикам, которые уже немного знакомы со стандартной библиотекой языка, хотят глубже изучить Boost, упростить и повысить качество разработки приложений. Уверен, что информация, которую я собрал в книге, будет полезна — всё больше библиотек Boost становятся частью стандарта. Сегодня предлагаю прочитать главу, посвящённую работе с файлами. В ней я рассказываю о перечислении файлов в каталоге, стирании и создании файлов и каталогов, а также о самом быстром способе чтения. Надеюсь, будет интересно. И, пожалуйста, не забывайте делиться впечатлениями в комментариях.
Перечисление файлов в каталоге
Существуют функции и классы стандартной библиотеки для чтения и записи данных в файлы. Но до появления C++17 в ней не было функций для вывода списка файлов в каталоге, получения типа файла или получения прав доступа к файлу.
Давайте посмотрим, как можно исправить эту несправедливость с помощью Boost. Мы будем создавать программу, которая перечисляет имена файлов, права на запись и типы файлов в текущем каталоге.
Знание основ C++ более чем достаточно для использования этого рецепта. Этот рецепт требует линковки с библиотеками boost_system и boost_filesystem.
Как это делается…
Этот и последующий рецепты посвящены переносимым оберткам для работы с файловой системой.
-
Нам нужно подключить следующие два заголовочных файла:
#include #include
int main() < boost::filesystem::directory_iterator begin("./");
boost::filesystem::directory_iterator end; for (; begin != end; ++ begin)
boost::filesystem::file_status fs = boost::filesystem::status(*begin);
switch (fs.type()) < case boost::filesystem::regular_file: std::cout if (fs.permissions() & boost::filesystem::owner_write) < std::cout else
std::cout /*for*/ > /*main*/
Готово. Теперь, если мы запустим программу, она выведет что-то вроде этого:
FILE W "./main.o"
FILE W "./listing_files"
DIRECTORY W "./some_directory"
FILE W "./Makefile"
Как это работает…
Функции и классы Boost.Filesystem просто оборачивают системные вызовы для работы с файлами.
Обратите внимание на использование знака /».» на этапе 2. Системы POSIX используют косую черту для указания путей; Windows по умолчанию использует обратную косую черту. Тем не менее Windows также понимает косую черту, а даже если бы не понимала, то библиотека Boost позаботилась бы о неявном преобразовании формата пути.
Посмотрите на этап 3, где мы вызываем конструктор по умолчанию для класса boost: filesystem: directory_iterator. Этот конструктор работает по аналогии с конструктором по умолчанию класса std: istream_iterator, — создает итератор конца диапазона.
Этап 4 сложен не потому, что эту функцию трудно понять, а из-за того, что происходит много преобразований. Разыменование итератора begin возвращает boost: filesystem: directory_entry, который неявно преобразуется в boost: filesystem: path, использующийся в качестве параметра для функции boost: filesystem: status. На самом деле можно написать намного лучше:
boost::filesystem::file_status fs = begin->status();
Совет:
Внимательно прочитайте справочную документацию, чтобы избежать ненужных неявных преобразований.
Этап 5 очевиден, поэтому мы переходим к этапу 6, где неявное преобразование в boost: filesystem: path происходит снова. Более явное решение выглядит так:
std::cout path()
Здесь begin→path () возвращает константную ссылку на переменную
boost: filesystem: path, которая содержится в boost: filesystem: directory_entry.
Дополнительно…
Boost.Filesystem является частью C++17. Все содержимое в C++17 находится в одном заголовочном файле в пространстве имен std: filesystem. Версия стандартной библиотеки несколько отличается от Boost-версии, в основном за счет использования перечислений с областью видимости (enum class) там, где Boost.Filesystem использовала просто перечисление без области видимости.
Совет:
Есть класс directory_entry, который обеспечивает кеширование информации о файловой системе. Так что если вы много работаете с файловой системой и запрашиваете различную информацию, попробуйте использовать directory_entry для лучшей производительности.
Как и в случае с другими библиотеками Boost, Boost.Filesystem работает с компиляторами для стандарта, предшествующего C++17, и даже с компиляторами для стандарта, предшествующего C++11.
См. также
- Рецепт «Стирание и создание файлов и каталогов» покажет еще один пример использования Boost.Filesystem;
- прочтите официальную документацию по Boost.Filesystem, чтобы получить больше информации о ее возможностях на странице http://boost.org/libs/filesystem;
- рабочую версию проекта C++17 можно найти по адресу http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf.
Стирание и создание файлов и каталогов
Давайте рассмотрим следующие строки кода:
std::ofstream ofs("dir/subdir/file.txt"); ofs
В этих строках мы пытаемся записать что-то в файл file.txt в каталоге dir/ subdir. Если такой директории нет, эта попытка будет неудачной.
В этом рецепте мы создадим каталог и подкаталог, запишем некие данные в файл и попробуем создать символическую ссылку. Если создание символической ссылки не удается, то мы удалим созданные сущности. В примере мы также будем избегать использования исключений в качестве механизма сообщения об ошибках, отдавая предпочтение чему-то вроде кодов возврата.
Давайте посмотрим, как можно сделать это элегантно, используя Boost.
Подготовка
Для этого рецепта требуются базовые знания C++ и класса std: ofstream.
Boost.Filesystem не является библиотекой header-only, поэтому код в этом ре-
цепте требуется линковать с библиотеками boost_system и boost_filesystem.
Как это делается…
Мы продолжаем работать с переносимыми обертками для файловой системы и в этом рецепте посмотрим, как изменить содержимое каталога.
-
Как всегда, нам нужно подключить несколько заголовочных файлов:
#include #include #include
int main() < boost::system::error_code error;
boost::filesystem::create_directories("dir/subdir", error); assert(!error);
std::ofstream ofs("dir/subdir/file.txt"); ofs
boost::filesystem::create_symlink( "dir/subdir/file.txt", "symlink", error);
if (!error) < std::cerr
> else < std::cerr /*if (!error)*/ > /*main*/
Как это работает…
boost: system: error_code может хранить информацию об ошибках и широко используется во всех библиотеках Boost.
Если вы не предоставите экземпляр boost: system: error_code для функций Boost.Filesystem, код будет компилироваться. В этом случае при возникновении ошибки будет выброшено исключение boost: filesystem: filesystem_error.
Внимательно посмотрите на этап 3. Мы использовали функцию boost: filesystem: create_directories вместо boost: filesystem: create_directory, потому что последняя не может создавать вложенные подкаталоги. Та же самая история с boost: filesystem: remove_all и boost: filesystem: remove. Первая удаляет каталоги, которые могут содержать файлы и подкаталоги. Вторая удаляет один файл.
Остальные шаги просты для понимания и не должны вызывать проблем.
Дополнительно…
Класс boost: system: error_code является частью C++11. Его можно найти в заголовочном файле в пространстве имен std. Классы Boost.Filesystem являются частью C++17.
Наконец, небольшая рекомендация для тех, кто собирается использовать Boost.Filesystem. Когда ошибки при работе с файловой системой являются частым явлением, или приложение требует высокой отзывчивости/производительности, используйте класс boost: system: error_codes. В противном случае для обработки ошибок перехват исключений будет предпочтительнее и надежнее.
См. также
Рецепт «Перечисление файлов в каталоге» также содержит информацию о Boost. Filesystem. Прочтите официальную документацию по адресу http://boost.org/libs/filesystem, где приводится больше информации и примеров.
Самый быстрый способ чтения файлов
В интернете люди спрашивают: «Какой самый быстрый способ чтения файлов?» Давайте усложним задачу для этого рецепта: какой самый быстрый и переносимый способ чтения двоичных файлов?
Подготовка
Для этого рецепта требуются базовые знания C++ и std: fstream.
Подготовка
Техника из этого рецепта широко используется приложениями, чувствительными к производительности ввода-вывода. Это самый быстрый способ чтения файлов.
Как это делается…
Техника из этого рецепта широко используется приложениями, чувствительными к производительности ввода-вывода. Это самый быстрый способ чтения файлов.
-
Нам нужно подключить два заголовка из библиотеки Boost.Interprocess:
#include #include
const boost::interprocess::mode_t mode = boost::interprocess::read_only; boost::interprocess::file_mapping fm(filename, mode);
boost::interprocess::mapped_region region(fm, mode, 0, 0);
const char* begin = static_cast( region.get_address() );
Готово! Теперь мы можем работать с файлом, как с обычной памятью:
const char* pos = std::find( begin, begin + region.get_size(), '\1' );
Как это работает…
Все популярные операционные системы имеют возможность отображать файл в адресное пространство процессов. После того как такое отображение было выполнено, процесс может работать с этими адресами так же, как с обычной памятью. Операционная система сама заботится обо всех файловых операциях, таких как кеширование и упреждающее чтение.
Почему это быстрее, чем традиционные операции чтения и записи? Это связано с тем, что в большинстве случаев чтение и запись реализуются как отображение в память и копирование данных в указанный пользователем буфер. Таким образом, чтение обычно делает немного больше, чем отображение.
Как и в случае с std: fstream из стандартной библиотеки, мы должны передать режим открытия файла. См. этап 2, где мы предоставили режим boost: interprocess: read_only.
См. этап 3, где мы отобразили весь файл сразу. Эта операция действительно очень быстрая, потому что ОС не читает все данные с диска, а сразу возвращает нам управление и ожидает запросов к части отображаемой области. После запроса ОС загружает запрошенную часть файла с диска в память. Как мы видим, операции отображения в память являются ленивыми, а размер отображаемой области не влияет на производительность.
Однако 32-разрядная ОС не может отображать в память большие файлы, поэтому вам придется отображать их по частям. Операционные системы POSIX (Linux) требуют определения макроса _FILE_OFFSET_ BITS=64 для всего проекта, чтобы работать с большими файлами на 32-битной платформе. В противном случае ОС не сможет отобразить части файла, размер находится за границей первых 4 ГБ.
Теперь пришло время измерить производительность:
$ TIME="%E" time ./reading_files m mapped_region: 0:00.08 $ TIME="%E" time ./reading_files r ifstream: 0:00.09 $ TIME="%E" time ./reading_files a C: 0:00.09
Как и ожидалось, отображенные в память файлы немного быстрее по сравнению с традиционными операциями чтения. Также видно, что чистые методы C имеют такую же производительность, что и класс C++ std: ifstream, поэтому по возможности не используйте FILE* функции в C++. Они предназначены только для C, а не для C++!
Для обеспечения оптимальной производительности std: ifstream не забудьте открыть файлы в двоичном режиме и читать данные блоками:
std::ifstream f(filename, std::ifstream::binary); // . char c[kilobyte]; f.read(c, kilobyte);
Дополнительно…
К сожалению, классы для отображения файлов в память не являются частью C++20, и, похоже, их не будет и в C++23.
Запись в области с отображением в память также является очень быстрой операцией. Операционная система кеширует записи и не сбрасывает изменения на диск немедленно. Существует разница между кешированием данных в ОС и std: ofstream. В случае std: ofstream данные кешируются приложением, и если работа приложения аварийно завершается, закешированные данные могут быть потеряны. Когда данные кешируются ОС, завершение работы приложения не приводит к их потере. Сбои питания и сбои ОС приводят к потере данных в обоих случаях.
Если несколько процессов отображают один файл и один из процессов изменяет отображаемую область, то изменения сразу видны другим процессам (даже без фактической записи данных на диск! Современные ОС очень умные! Только не забывайте про синхронизацию доступа).