C - должен ли exec немедленно следовать за форком в многопоточном процессе? - PullRequest
10 голосов
/ 19 ноября 2010

Положение: У меня есть многопоточная программа, написанная на C. Если один из потоков разветвляется, дочерний процесс заменяется другим с помощью exec (), и родительский процесс ожидает завершения дочернего процесса.

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

1010 * Гипотеза * Правильно ли я считаю, что за время между дочерним процессом, создаваемым fork () и замененным exec (), дочерний процесс, являющийся копией родительского, будет иметь все потоки родительского и, следовательно, эти потоки будет работать - хотя и в течение очень короткого периода?

Если это так, является ли правильным решением для вызова exec () сразу после fork ()?

Ответы [ 3 ]

10 голосов
/ 19 ноября 2010

В новом процессе будет работать только поток, который вызывает fork. Тем не менее, существуют ограничения на то, какие функции вы можете вызывать до exec. От fork:

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

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

РЕДАКТИРОВАТЬ: страница pthread_atfork объясняет, как библиотека может защитить себя:

Ожидаемое использование - приготовление обработчик получает все блокировки мьютекса и выпуск двух других обработчиков вил их.

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

3 голосов
/ 19 ноября 2010

Как писал @Matthew в своем ответе, другие потоки из родительского процесса не будут существовать в дочернем процессе (если вы используете PThreads).

Обратите внимание, что если бы это было не так, это не помогло бы выполнить вызов exec () "сразу после" вызова fork, поскольку все еще существует вероятность того, что другие потоки будут выполняться до того, каквызов exec ().Однако вы можете контролировать это, блокируя мьютекс перед вызовом fork () - он будет по существу разрушен вызовом exec ().

0 голосов
/ 06 декабря 2010

Я тоже думал, что все потоки будут реплицироваться и в дочернем процессе. Но это не правда. Так как другие потоки не реплицируются в дочернем процессе, если вы используете мьютексы / блокировки перед exec, вам нужно убедиться, что обработчики вил написаны для их правильной обработки. Вот статья об этом. http://learnwithtechies.com/tech/index.php?option=com_content&view=article&id=15:fork-in-multithreaded-environment&catid=10:unix

...