Муфтезы pthread работают через потоки, если в общей памяти?
Я нашел это:
Метод быстрого межпроцессного синхронизации
Раньше я полагал, что мьютекс pthread может использоваться только между двумя потоками в одном и том же адресном пространстве.
Вопрос/ответы там, кажется, подразумевают:
Если у меня есть два отдельных процесса A и B. Они имеют область общей памяти M. Я могу поместить мьютекс pThread в M, заблокировать A, заблокировать в B, разблокировать A; и B больше не будет блокировать мьютекс. Это верно? Можно ли делиться мьютексами pThread в двух отдельных процессах?
Изменить: я использую С++, на MacOSX.
Ответы
Ответ 1
Вам нужно сказать, что мьютекс должен быть разделен между процессами при его входе:
http://www.opengroup.org/onlinepubs/007908775/xsh/pthread_mutexattr_setpshared.html
Обратите внимание, в частности, "Значение по умолчанию для атрибута - PTHREAD_PROCESS_PRIVATE", что означает, что доступ к нему из разных процессов - это поведение undefined.
Ответ 2
Если ваша библиотека C/pthread соответствует, вы должны быть в состоянии определить, поддерживает ли она мьютексы, разделяемые несколькими процессами, если _POSIX_THREAD_PROCESS_SHARED
определяется как значение, отличное от -1
, или путем запроса конфигурации системы во время выполнения с помощью sysconf(_SC_THREAD_PROCESS_SHARED)
если этот макрос проверки функций undefined.
EDIT: как Стив указал, вам нужно будет явно настроить мьютекс для совместного использования между процессами, если платформа поддерживает эту функцию как я описал выше.
Ответ 3
Я был обеспокоен тем, что может существовать условие, при котором мьютекс в общей памяти может некорректно вести себя должным образом, поэтому я немного поработал и придумал некоторые документы, которые рассматривают проблему как проблему:
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 и т.д.?