C # и C ++ Синхронизация между процессами

У нас есть 2 приложения. Один написан на C #, а другой - на C ++. Нам нужно поддерживать счетчик (в памяти), совместно используемый этими процессами. Каждый раз, когда запускается одно из этих приложений, ему необходимо проверять этот счетчик и увеличивать его, и каждый раз при завершении работы приложения ему необходимо уменьшать счетчик. Если в приложении происходит сбой или завершение работы с помощью диспетчера задач, нам также необходимо, чтобы счетчик уменьшился.
Мы подумали об использовании одного из объектов синхронизации ОС, например MUTEX.
Мой вопрос: что это за объект синхронизации лучший для перекрестного процесса (когда один C #, а другой C ++)

Надеюсь, мой вопрос был ясен.
Большое спасибо,

Ади Барда


person Adi Barda    schedule 02.02.2010    source источник
comment
Это в Windows или в нескольких ОС?   -  person Jon Cage    schedule 02.02.2010
comment
Основная проблема, которую я вижу, заключается в том, что в вашем требовании указано, что в случае сбоя программы вам нужно уменьшить значение. Этого было бы достаточно сложно добиться при любой надежности.   -  person ScaryAardvark    schedule 02.02.2010
comment
@ Страшно: если вы поймаете все исключения, вы все равно сможете выполнить декремент. Если вы убиваете процесс, вы застреваете, если не измените значение в памяти при запуске процесса, и он не выйдет из строя между запуском и изменением мьютекса ...   -  person Jon Cage    schedule 02.02.2010
comment
Джон: Из документации MS я понимаю, что могу использовать мьютекс в случае сбоя приложения: ... Если поток завершается при владении мьютексом, то считается, что мьютекс заброшен. Состояние мьютекса устанавливается как «сигнализировано», и следующий ожидающий поток получает право владения. Начиная с версии 2.0 .NET Framework, в следующем потоке, который получает брошенный мьютекс, создается исключение AbandonedMutexException. До версии 2.0 .NET Framework никаких исключений не возникало ...   -  person Adi Barda    schedule 02.02.2010
comment
@Jon. Я бы не стал считать перехват всех исключений сбоем. Это нормальное завершение работы. это может быть упорядоченное завершение работы перед лицом чего-то неожиданного, но это все же не сбой. Даже установка обработчиков at_exit и т. Д. Не поможет. Единственное, что вы можете сделать, это создать процесс-оболочку, который отслеживает состояние реального процесса, и если он выйдет из строя, вы можете уменьшить счетчик .. Но что произойдет, если ваш процесс-оболочка умрет ...   -  person ScaryAardvark    schedule 02.02.2010
comment
@ Ади. Да, вы можете использовать мьютекс для защиты общего счетчика, но как узнать, правильно ли он был уменьшен в случае сбоя ..   -  person ScaryAardvark    schedule 02.02.2010
comment
@Scary ... Итак, пул наблюдающих процессов; шансы, что все они упадут одновременно, довольно малы, не так ли? ;-)   -  person Jon Cage    schedule 02.02.2010
comment
@Jon. Да, это замкнутый круг. Как я уже сказал. Кто наблюдает за наблюдателями :)   -  person ScaryAardvark    schedule 02.02.2010


Ответы (3)


Вам может сойти с рук именованный семафор. Семафор - это в основном счетчик, он здесь, чтобы позволить разработчикам ограничивать количество потоков / процессов, которые обращаются к некоторому ресурсу. Обычно так работает

  1. Вы создаете семафор с максимальным количеством N.
  2. N потоков вызывают на нем функцию ожидания, WaitForSingleObject или аналогичную, и каждый из них продолжается без ожидания. Каждый раз внутренний счетчик семафоров опускается.
  3. Поток N + 1 также вызывает функцию ожидания, но поскольку внутренний счетчик нашего семафора теперь равен 0, он должен ждать.
  4. Один из наших первых N потоков освобождает семафор, вызывая функцию ReleaseSemaphore. Эта функция увеличивает внутренний счетчик семафора.
  5. Нашему ожидающему потоку теперь не нужно ждать, поэтому он возобновляется, но счетчик семафоров возвращается к 0.

Я не думаю, что вы хотите использовать его именно так. Итак, вместо этого вам следует:

  1. Создайте именованный семафор с нулевым начальным счетчиком.
  2. При запуске приложения сразу отпустите его, увеличив счетчик. Вы получите предыдущее значение счетчика во время этого вызова.
  3. Когда приложение завершится, вызовите WaitForSingleObject(hSemaphore, 0), уменьшив счетчик. 0 означает, что вы не хотите ждать.

Все это довольно просто.

In C++

//create semaphore
HANDLER hSemaphore = CreateSemaphore(NULL, 0, BIG_NUMBER, "My cool semaphore name");
//increase counter
LONG prev_counter;
ReleaseSemaphore(hSemaphore, 1, &prev_counter);
//decrease counter
WaitForSingleObject(hSemaphore, 0);

In C#

using System.Threading;
//create semaphore
Semaphore sem = new Semaphore(0, BIG_NUMBER, "My cool semaphore name");
//increase counter
int prev_counter = sem.Release(); 
//decrease counter
sem.WaitOne(0);

Очевидно, что имена и BIG_NUMBER должны совпадать.

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

person vava    schedule 02.02.2010
comment
не подходят ли семафоры только для одного и того же процесса? - person Adi Barda; 02.02.2010
comment
События, мьютексы, семафоры и времена могут иметь имена, которые делают их доступными для всей системы. msdn.microsoft.com/en-us/library/ ms684292% 28VS.85% 29.aspx - person vava; 02.02.2010
comment
В зависимости от протоколов вашего приложения вы можете использовать какой-либо IPC для согласования именованного семафора (в том маловероятном случае, когда то, что вы выбираете, используется другим процессом) - person C. Tewalt; 15.01.2016

Похоже, вам нужен именованный семафор (CreateSemaphore): http://msdn.microsoft.com/en-us/library/ms682438(VS.85).aspx для C ++, который подходит для увеличения / уменьшения.

В C # у вас есть класс System.Threading.Semaphore.

person Community    schedule 02.02.2010
comment
не подходят ли семафоры только для одного и того же процесса? - person Adi Barda; 02.02.2010
comment
Нет, как вы, вероятно, уже знаете из ответа vava на другой ваш комментарий. - person ; 03.02.2010

Взгляните на этот поток, чтобы узнать о методах совместного использования некоторой памяти для синхронизации. целей или здесь для некоторых предложений по синхронизации в .net / c #.

Если есть доступные методы .net, они должны работать как для C ++, так и для C #.

person Jon Cage    schedule 02.02.2010