pthread_atfork идиома блокировки сломана? - PullRequest
4 голосов
/ 29 марта 2011

Стандартная идиома для использования pthread_atfork должна заключаться в получении всех блокировок в обработчике pre-fork и снятии их как в родительском, так и в дочернем обработчиках. Однако, насколько я могу судить, это невозможно. pthread_mutex_unlock указывается либо для неопределенного поведения (в случае мьютексов нормального типа или типа по умолчанию), либо для сбоя (в случае мьютексов с рекурсивным или проверяющим ошибки), если вызывающий поток не является владельцем мьютекса. И в дочернем обработчике, зарегистрированном с pthread_atfork, вызывающий поток является основным потоком вновь созданного процесса, и поэтому не может быть владельцем мьютекса.

Я ошибаюсь или вся идиома pthread_atfork нарушена замыслом и практически невозможна в использовании?

Редактировать: Я также не вижу ни одного допустимого (переносимого) обходного пути для этой проблемы. В идеале можно просто уничтожить и повторно инициализировать мьютексы в дочернем процессе, за исключением того, что вызов pthread_mutex_destroy для инициализированного мьютекса определен как неопределенное поведение, чтобы приспособиться к нелепым реализациям, где мьютексы не являются POD, но включают ссылку на некоторое ядро. объект уровня.

1 Ответ

1 голос
/ 29 марта 2011

Я думаю, что это соответствующий текст от человека:

Когда вызывается fork (), только вызывающий поток дублируется в дочерний процесс . синхронизация переменные остаются в том же состоянии у ребенка, как они были у родителя в временная вилка () была вызвана. Таким образом, для пример, блокировки мьютекса могут удерживаться потоками, которых больше нет в дочерний процесс, и любой связанный состояния могут быть противоречивы. Родительский процесс может избежать этого явным код, который получает и снимает блокировки решающее значение для дочерний через pthread_atfork (). Кроме того, любые критические темы необходимо воссоздать и повторно инициализировать к правильное состояние у ребенка (также через pthread_atfork ()).

Поток, который выполняет обработчик atfork в child, является точной копией потока, который выполнил обработчик подготовки atfork в parent, и, следовательно, имеет право разблокировать мьютексы.

...