4.6. Сравнение процессов и потоков
В некоторых программах, связанных с параллельным выполнением операций, сделать выбор в пользу процессов или потоков может оказаться достаточно сложно. Приведем рад правил, которые помогут читателям выбрать наилучшую модель для своих программ.
■ Все потоки программы должны выполнять один и тот же код. В то же время дочерний процесс может запустить другой исполняемый файл с помощью функции exec().
■ Неправильно работающий поток способен помешать другим потокам того же процесса, поскольку все они используют одни и те же ресурсы. Например, неверное обращение к указателю может привести к искажению области памяти, используемой другим потоком. Процесс лишен возможности это делать, так как у него своя копия памяти,
■ Копирование памяти, требуемой для дочернего процесса, приводит к снижению производительности процессов в сравнении с потоками. Но на самом деле операция копирования выполняется только тогда, когда содержимое памяти изменяется, поэтому снижение производительности оказывается минимальным, если дочерний процесс обращается к памяти только для чтения данных.
■ Потоки требуются программам, в которых необходима тонкая настройка параллельной работы. Потоки, например, хорошо подходят в том случае, когда задание можно разбить на ряд почти идентичных задач. Процессы в основном работают не зависимо друг от друга.
■ Совместное использование данных несколькими потоками — тривиальная задача, ведь потоки имеют общий доступ к ресурсам (необходимо, правда, внимательно следить за тем, чтобы не возникало состояние гонки). В случае процессов требуется задействовать особый механизм взаимодействия, описанный в главе 5, "Взаимодействие процессов". Это делает программы более громоздкими, зато уменьшает вероятность ошибок, связанных с параллельной работой.
Глава 5
Взаимодействие процессов
В главе 3, "Процессы", описывалась процедура создания процесса и рассказывалось о том, как родительский процесс может получить код завершения дочернего процесса. Это простейшая форма взаимодействия двух процессов, но не самая эффективная. Рассмотренные в главе 3 механизмы позволяли процессу-предку общаться с процессом-потомком только посредством аргументов командной строки и переменных среды, а все, что мог сделать для предка потомок, — вернуть свой код завершения. Такие механизмы не позволяют контролировать выполняющийся процесс или обращаться к внешнему, независимому процессу.
В этой главе будет показано, как обойти упомянутые ограничения путем организации взаимодействия процессов. Между собой могут общаться не только родительский и дочерний процессы, но также "неродственные" процессы и даже процессы, выполняющиеся на разных компьютерах.
Взаимодействие процессов — это механизм обмена данными между процессами. Взять, к примеру, ситуацию, когда броузер запрашивает Web-страницу у сервера, который в ответ высылает HTML-данные. Обычно при этом используются сокеты, работающие через телефонное соединение. Или другой пример: пользователь вводит команду ls | lpr, чтобы вывести на печать список файлов в каталоге. Интерпретатор команд создает два отдельных процесса — ls и lpr — и соединяет их каналом, который представлен символом '|'. Канал — это однонаправленный способ передачи данных от одного процесса к другому. Процесс ls записывает данные в канал, а процесс lpr читает данные из него.
В этой главе рассматриваются пять способов взаимодействия процессов.
■ Совместно используемая память — процессы могут просто читать и записывать данные в рамках заданной области памяти.
■ Отображаемая память — напоминает совместно используемую память, но организуется связь с файлами.
■ Каналы — позволяют последовательно передавать данные от одного процесса к другому.
■ FIFO-файлы — в отличие от каналов, с ними работают несвязанные процессы, поскольку у такого файла есть имя в файловой системе и к нему может обратиться любой процесс.
■ Сокеты — соединяют несвязанные процессы, работающие на разных компьютерах.
Различия между способами взаимодействия определяются следующими критериями:
■ ограничено ли взаимодействие рамками связанных процессов (имеющих общего предка) или же соединяются процессы, выполняющиеся в одной файловой системе либо на разных компьютерах: