2012-04-09 3 views
12

В C++, используя pthreads, что происходит с вашими другими потоками, если один из ваших потоков вызывает fork?Что происходит с другими потоками, когда один поток forks()?

Похоже, что нити не следуют. В моем случае я пытаюсь создать демона, и я использую fork() с родительским выходом, чтобы деамонизировать его. Однако в новом пути через код я создаю некоторые потоки перед вилкой, а некоторые после. Есть ли простой способ изменить право собственности на потоки на новый разветвленный процесс, а не перемещать все мои создания потоков после вилки?

+0

Как вы уже выяснили, в настоящее время, это очень плохая идея. Если у вас есть такая озабоченность в реальном приложении, я бы посоветовал выяснить причину, почему вы должны это сделать, выяснить, как правильно это сделать, и сделать правильный рефакторинг: D – Dacav

ответ

18

Ничего. Только поток, вызывающий fork(), получает дубликат. Детский процесс должен начинать любые новые потоки. Потоки родителей остались одни.

+1

Что происходит с потоками, когда родительский вывод fork() s? – WilliamKF

+0

@WilliamKF http://stackoverflow.com/questions/395877/are-child-processes-created-with-fork-automatically-killed-when-the-parent-is –

0

Ничего, если только кто-то не вытесняется потоком, выполняющим новый процесс.

0

В POSIX, когда многопоточный процесс вилки, дочерний процесс выглядит точно так же, как копия родителя, но в котором все потоки остановились на своих дорогах и исчезли.

Это очень плохо, если резьбы держат замки.

По этой причине существует неосновный механизм, называемый pthread_atfork, в котором вы можете зарегистрировать обработчики для этой ситуации.

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

Помимо замков мьютексов, потоки могут иметь другие ресурсы, такие как данные, зависящие от потока, безводные от pthread_setspecific, которые доступны только для потока (и поток отвечает за очистку его через деструктор).

В дочернем процессе такой деструктор не работает. Адресное пространство копируется, но поток и его конкретное значение потока не существуют, поэтому память просочилась в дочерний элемент. Это можно и должно обрабатывать с помощью обработчиков pthread_atfork.

3

Как правило, очень плохо развивать нить. Предполагается, что разветвленный процесс является полной копией родителя, кроме как с потоками это не так. Существует функция pthread_atfork(), которая иногда помогает. Если вы должны разветвить поток, лучше всего позвонить по телефону exec() сразу после fork().

Я предлагаю вам прочитать предостережения от разработчиков POSIX в документации fork() и pthread_atfork() (см http://pubs.opengroup.org/onlinepubs/007904975/functions/fork.html и http://pubs.opengroup.org/onlinepubs/007904975/functions/pthread_atfork.html).

Из fork() документации:

fork() функция, таким образом, используется только для запуска новых программ, а также последствие вызова функций, которые требуют определенных ресурсов между вызовом fork() и призывом к exec функциям являются не определено.

Смежные вопросы