Работают ли мьютексы pthread в потоках, если они находятся в общей памяти? - PullRequest
22 голосов
/ 05 марта 2010

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

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

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

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

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

Ответы [ 3 ]

16 голосов
/ 06 марта 2010

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

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

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

6 голосов
/ 06 марта 2010

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

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

1 голос
/ 05 марта 2010

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

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 и т. Д.?

...