Блокировка чтения/записи межпроцессного мьютекса

Я пытаюсь установить межпроцессное взаимодействие на C/C++ в среде Windows.

Я создаю файл страницы общей памяти, и два процесса получают доступ к этому файлу. Это вот так:

Процесс 1: Инициализировать разделяемую область памяти. Подождите, пока Process2 заполнит его.

Process2: Получить дескриптор области общей памяти. Положите в него вещи.

Я также создаю именованный мьютекс в процессе1. Теперь процесс1 получает право собственности на мьютекс вскоре после его создания (используя WaitSingleObject). Очевидно, в области памяти ничего нет, поэтому мне нужно освободить мьютекс. Теперь мне нужно дождаться заполнения памяти, а не пытаться снова захватить мьютекс.

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

Однако, согласно документации MS по переменным состояния, они не используются совместно процессами, что ясно из их инициализации, поскольку они не являются named.

Кроме того, область разделяемой памяти может содержать до одного элемента в любой момент времени, что означает, что процесс 2 не может повторно заполнить ее после ее заполнения, если только процесс 1 не извлечет свою информацию.

Из данного описания видно, что для этой цели лучше всего подходят условные переменные (или мониторы). Так есть ли способ обойти это?


person Everyone    schedule 13.11.2017    source источник
comment
Семафоры......... две семы, A, B, инициализируются в 0. P1 ожидает A. P2 заполняет буфер. P2 сигнализирует A и ожидает B. P1 обрабатывает данные буфера, затем сигнализирует B и возвращается обратно, чтобы снова ожидать A.   -  person Martin James    schedule 13.11.2017
comment
@MartinJames Я хотел их использовать, но они не работают как условные переменные. Мьютекс — это, по сути, семафор со счетчиком, равным единице. Мне нужно дождаться сигнала, а не ждать владения. Если бы я использовал семафоры, я все равно получил бы право собственности, как и при использовании мьютекса. Я не хочу владеть, пока кто-то другой не подаст мне сигнал.   -  person Everyone    schedule 13.11.2017
comment
«Мьютекс — это, по сути, семафор со счетчиком, равным единице», — нет, не совсем так.   -  person Martin James    schedule 13.11.2017
comment
@MartinJames Я знаю, что это не совсем так, но то, как это работает, очень похоже. Семафоры не могут решить мою проблему здесь. Я посмотрел их, прежде чем спрашивать.   -  person Everyone    schedule 13.11.2017
comment
Нет такого языка, как C/C++. Выберите язык.   -  person tambre    schedule 13.11.2017
comment
Два семафора - это ТОЧНО способ сделать то, что вы описываете. Очереди с длиной больше 1 потребуются два семафора и мьютекс (классическая очередь производитель-потребитель). Вы можете обойтись всего двумя семафорами, которые эффективно обмениваются «токеном доступа» между двумя процессами.   -  person Martin James    schedule 13.11.2017
comment
@tambre Серьезно? 1. Как это связано? 2. Есть C/C++, я использую стандартные классы C++ с C API.   -  person Everyone    schedule 13.11.2017
comment
@MartinJames На самом деле это имеет большой смысл. Я дам ему попробовать! Спасибо!   -  person Everyone    schedule 13.11.2017
comment
@Everyone Это связано с вашими тегами. C/C++ не является языком. Ваш код написан на С++ и компилируется как таковой (насколько я могу судить). Я бы посчитал тег C ненужным, поскольку вы просто ссылаетесь на C API, и вопрос конкретно не в проблеме использования такого API из C++ - остальная часть вашего кода находится на C++.   -  person tambre    schedule 13.11.2017
comment
@tambre Термин C/C++ широко используется, поскольку коды C довольно часто используются с C++. Да, мой код по сути является C++ и скомпилирован как таковой, и он действительно вызывает API-интерфейсы C, поэтому я использовал термин C/C++. Да, тег не нужен, я его удалю :)   -  person Everyone    schedule 13.11.2017


Ответы (3)


Условные переменные могут использоваться в процессе, но не между процессами.

Попробуйте NamedPipe с PIPE_ACCESS_DUPLEX в качестве открытого режима. Так что у вас есть варианты связи от обоих процессов.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365150(v=vs.85).aspx

person Pavan Chandaka    schedule 13.11.2017

Мьютекс (как и большинство примитивов синхронизации) является объектом для каждого процесса и может использоваться разными потоками в рамках одного процесса. Вы не можете разделить его между процессами (по крайней мере, в Unix).

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

person Jesper Juhl    schedule 13.11.2017
comment
Не совсем так. Windows API имеет named-mutex, который может совместно использоваться несколькими процессами. Из моего вопроса ясно, что я пытаюсь внедрить IPC, а не использовать уже существующие механизмы. - person Everyone; 13.11.2017
comment
Вы можете использовать объект мьютекса для защиты общего ресурса от одновременного доступа нескольких потоков или процессов.... From msdn.microsoft.com/en-us/library/windows/desktop/ - person Everyone; 13.11.2017
comment
@ Все в порядке, кажется, мой ответ был слишком ориентирован на Unix - я мало работаю с Windows. Прости. - person Jesper Juhl; 13.11.2017
comment
Я так понял, поскольку в Windows есть кросс-процессы. - person Everyone; 13.11.2017

Я использовал события для этого раньше. Используйте 2 именованных события автоматического сброса. 1 событие готовности данных и одно событие готовности буфера. Модуль записи ожидает готовности буфера, записывает данные и устанавливает событие готовности данных. Читатель ожидает события готовности данных, считывает память и устанавливает событие готовности буфера. Если все сделано правильно, вам не нужен мьютекс.

person Mike    schedule 13.11.2017