Работают ли мьютексы pthread в потоках, если они находятся в общей памяти?

Я нашел это: быстрый метод синхронизации между процессами

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

Вопрос / ответы там, кажется, подразумевают:

Если у меня есть две отдельные процедуры A и B. Они имеют общую область памяти M. Я могу поместить мьютекс pThread в M, заблокировать в A, заблокировать в B, разблокировать в A; и B больше не будет блокировать мьютекс. Это правильно? Могут ли мьютексы pThread быть разделены на два отдельных процесса?

Редактировать: я использую C++, на MacOSX.

3 ответа

Вы должны указать мьютексу, что он должен использоваться для совместного использования процесса при его запуске:

http://www.opengroup.org/onlinepubs/007908775/xsh/pthread_mutexattr_setpshared.html

В частности, обратите внимание: "Значением атрибута по умолчанию является PTHREAD_PROCESS_PRIVATE", что означает, что доступ к нему из разных процессов является неопределенным поведением.

Если ваша библиотека C/pthread соответствует, вы сможете определить, поддерживает ли она мьютексы, совместно используемые несколькими процессами, проверив, _POSIX_THREAD_PROCESS_SHARED макрос функционального теста определяется значением, отличным от -1 или путем запроса конфигурации системы во время выполнения, используя sysconf(_SC_THREAD_PROCESS_SHARED) если этот макрос тестирования функции не определен.

РЕДАКТИРОВАТЬ: Как отметил Стив, вам нужно явно настроить мьютекс для совместного использования между процессами, предполагая, что платформа поддерживает эту функцию, как я описал выше.

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

https://computing.llnl.gov/tutorials/pthreads/

Дальнейшее копание, однако, показало, что более старые версии glibc страдали проблемами в мьютексах с общей памятью: (Это древнее изменение, но оно иллюстрирует это.)

in linuxthreads/mutex.c
int __pthread_mutexattr_setpshared(...) {
    /* For now it is not possible to shared a conditional variable. */
    if (pshared != PTHREAD_PROCESS_PRIVATE)
    return ENOSYS; 
}

Без более подробной информации о том, какую реализацию pthread вы используете, трудно сказать, в безопасности вы или нет.

Мое беспокойство вызывает то, что многие реализации (и некоторые целые языки, такие как perl, python и ruby) имеют объект глобальной блокировки, который управляет доступом к общим объектам. Этот объект не будет разделен между процессами и, следовательно, в то время как ваши мьютексы, вероятно, будут работать большую часть времени, вы можете столкнуться с двумя процессами, одновременно управляющими мьютексом одновременно.

Я знаю, что это противоречит определению мьютекса, но это возможно:

Если два потока работают одновременно в разных процессах, это означает, что они находятся на разных ядрах. Оба получают объект глобальной блокировки и манипулируют мьютексом в разделяемой памяти. Если реализация pthread форсирует обновление мьютекса через кэши, оба потока могут закончить обновление одновременно, думая, что они держат мьютекс. Это просто возможный вектор отказа, который приходит на ум. Там может быть любое количество других. Каковы особенности вашей ситуации - ОС, версия pthreads и т. Д.?

Другие вопросы по тегам