Так как любой процесс содержит хотя бы одну нить, создание (т.е. порождение) и завершение процессов подразумевает создание и завершение нитей. В этом разделе рассматривается взаимодействие нитей и процессов при порождении и завершении процессов.
Дополнительные сведения о запуске и завершении процессов приведены в следующих разделах:
Разработчики программ для AIX пользуются функцией fork для двух целей:
В программе с несколькими нитями новые потоки управления создаются не функцией fork, а функцией pthread_create. Функцию fork следует применять только для запуска программ.
Функция fork дублирует не весь родительский процесс, а только ту его нить, из которой была вызвана функция; дочерний процесс будет процессом с одной нитью. Вызывающая нить родительского процесса становится главной нитью дочернего процесса, даже если в родительском процессе она не была главной. Следовательно, при возврате главной нити дочернего процесса из процедуры точки входа дочерний процесс завершается.
При дублировании родительского процесса функция fork дублирует и все переменные синхронизации, включая их состояния. Это может привести к нарушению целостности ресурсов в случае, когда нить дочернего процесса установила взаимную блокировку, а затем завершилась.
Настоятельно рекомендуется пользоваться функцией fork только для запуска новых программ, а после вызова функции fork по возможности сразу же вызывать в дочернем процессе функцию exec.
К сожалению, при работе с многонитевыми библиотеками перечисленных выше правил предосторожности недостаточно. Прикладные программы могут "не знать", что работают с многонитевыми библиотеками, так что между вызовом функции fork и вызовом функции exec программа может вызывать любое количество библиотечных функций, как обычно. Прежние однонитевые версии программы не всегда могут соответствовать новым требованиям библиотеки нитей.
С другой стороны, многонитевым библиотекам необходимы средства защиты своего внутреннего состояния при вызове функции fork на случай, если из дочернего процесса будет вызвана какая-либо функция библиотеки. Эта проблема особенно актуальна для многонитевых библиотек ввода-вывода, так как практически всегда между вызовами функций fork и exec приходится вызывать какую-либо из библиотечных функций для перенаправления ввода-вывода.
С помощью функции pthread_atfork можно защитить библиотеки с несколькими нитями от последствий вызова функции fork из приложений. Эта функция также реализует стандартный механизм защиты приложений с несколькими нитями от последствий вызова fork из библиотеки или из самих приложений.
Функция pthread_atfork
регистрирует обработчики fork, которые необходимо вызвать до и после вызова
функции fork. Эти обработчики выполняются в той нити, из
которой вызывается функция fork. Существует три обработчика
fork:
Подготовительные обработчики вызываются в порядке стека (LIFO), а обработчики для родительского и дочернего процессов - в порядке простой очереди (FIFO). Благодаря этому в программах можно сохранить исходный порядок блокировки.
При завершении процесса с помощью явного или неявного вызова функции _exit завершаются все нити процесса. Не вызываются ни обработчики очистки, ни деструкторы данных для нитей.
Это связано с тем, что процесс завершается целиком, вместе со всеми своими нитями, так что очищается и освобождается вся память.
Обзор взаимодействия между нитями и процессами.
Список функций для взаимодействия между нитями и процессами.