std::mutex в разделяемой памяти не работает
У меня есть сценарий, когда к общей области памяти обращаются исключительно два разных процесса. Когда я запускаю процессы, первый процесс успешно блокирует мьютекс, обновляет память и разблокирует мьютекс. Но я замечаю, что когда второй процесс пытается его заблокировать, он все еще находится в тупиковом состоянии, ожидая разблокировки мьютекса.
Разница во времени между блокировкой мьютекса составляет 10 секунд для первого и второго процесса.
Я использую std::mutex. Пожалуйста, скажите мне, что мне не хватает.
2 ответа
Несмотря на ссылки, которые другие сделали в документации, классы std::mutex
а также std::shared_mutex
фактически работают между процессами при использовании в общей памяти в Linux. Я проверил с GCC 8.3.1 и Clang 6.0.1.
Стандартные реализации C++ для Linux используют pthreads. Предоставление pthreadsPTHREAD_PROCESS_SHARED
а также PTHREAD_PROCESS_PRIVATE
как атрибуты для pthread_mutex_t
а также pthread_rwlock_t
абстрагируются и используются по умолчанию std::mutex
а также std::shared_mutex
. Хотя в документации POSIX указано, что по умолчанию установлено ЧАСТНОЕ,pthread_mutex_t
а также pthread_rwlock_t
выделенные в разделяемой памяти блокируют конкурирующие процессы при блокировке. Это связано с тем, что фактическая реализация pthreads в Linux использует фьютексы, и они предназначены для использования в общей памяти даже в тех случаях, когда сопоставленные адреса могут различаться в разных процессах.
Возможно, что поведение PTHREADS_PROCESS_PRIVATE на самом деле сложнее реализовать, учитывая стратегию использования фьютексов для реализации мьютексов, и, как таковое, не реализовано молча.
Если вы действительно хотите, чтобы ваши мьютексы были приватными для процесса, просто не помещайте их в общую память. С другой стороны, если вы действительно хотите поделиться ими, будьте осторожны, поскольку это несоответствие стандартов может быть изменено.
Для надежности используйте Boost Interprocess.
Экземпляр std::mutex распространяется только на один процесс; он не способен к межпроцессной синхронизации / параллелизму. Он способен синхронизировать только дочерние потоки внутри родительского процесса.
Попробуйте использовать Boost или библиотеку синхронизации между процессами.
std::mutex не поддерживает межпроцессную работу, но в библиотеке pthread есть межпроцессный мьютекс, который вы можете использовать. Пример тут.