Процессы и IPC

Информация - Компьютеры, программирование

Другие материалы по предмету Компьютеры, программирование

Процессы и IPC

Сразу хочу огорчить программистов под Windows. К сожалению, некоторые из описанных ниже рецептов под Windows работать не будут. Я и сам долго скрежетал зубами, когда в ответ на переопределение STDOUT с помощью разветвляющего open в логи валились сообщения о том, что, мол, нет такой команды. Кого уж тут винить, не знаю, и искать не собираюсь. А советую всем, дабы не тратить свое драгоценное время, писать свои программы с расчетом на UNIX. Честно говоря, после всего, что я пережил, программируя под Windows, и узнав, что хостинг на IIS гораздо дороже (как очень редкий зверь что ли?) чем на UNIX-ах, я чуть из кресла не вывалился.

Процессы и с чем их едят

Давным-давно в одной далекой галактике жил-был DOS. И было у него всего-навсего 640 килов памяти, и мог выполнять он лишь только одну задачу. И появился грозный монстр Windows, который разделил процессорное время на части. Одну часть отвел он сонмищу процессов, а другую часть сонмищу потоков. И перекликались они с помощью мьютексов и семафоров. А данные передавались где как. Была там и общая куча (heap), и пайпы кой где работали… В общем рассказывать дальше думаю не имеет смысла. Еще много чего можно написать - все это скучно и отвлекает от основных целей.

Так как все здесь описанное связанно с Perl, который проектировался с ориентировкой на UNIX-системы, все системные фишки, которые здесь будут рассмотрены, относятся именно к UNIX-системам. Конечно, реализация Perl для Windows скрывает кое-какие несоответствия, но далеко не все. Так что, сильно не огорчайтесь, если что-то не работает. Безвыходных ситуаций не бывает. Пишите в форум, а еще лучше побольше экспериментируйте тогда все получится.

Итак, процесс это программа, код которой выполняется независимо от других программ. Может быть это и не академическое определение, но ведь и наша задача не обозвать это правильно, а понять как это работает и какая нам может быть от этого польза. Дабы не углубляться в системные тонкости, представим ситуацию на известных нам примерах.

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

Так вот, можно привести аналогию с многозадачной операционной системой: код вне процедур здесь будет представлять код ядра, который управляет всеми процессами- процедурами. Но здесь маленькое, но важное примечание. Когда в нашей аналогии ядро вызывает процедуру это запуск процесса, но не ее выполнение и ожидание ее завершения. Ядро где-то там у себя в хэше процессов создает новую пару имя- значение, имя которого есть имя процедуры, а значение номер строки последовательности операторов процедуры, на которой остановилось выполнение (то есть после запуска это 0). После этого, ядро перебирает все ключи из хэша и смотрит на имя и номер строки. Переходит на эту строку в нужной процедуре и выполняет, к примеру, следующие пять строк. Дальше следующая процедура, так до конца, а потом опять в начало хэша.

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

На самом деле все гораздо сложнее. Но нам не обязательно знать, как работает ядро операционной системы для того, что бы воспользоваться преимуществами многозадачной среды. Достаточно знать, что процесс это программа, выполняющаяся независимо. Очень важно уяснить, что процесс это не только код, но и данные. Даже если запускаются две одинаковые программы, данные они, скорее всего, будут обрабатывать по-разному.

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

fork;

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

На самом деле, оператор fork возвращает значение, которое используется для определения процесса. К примеру, выходит человек из-за угла, а ему кирпичом по голове. Очнулся, а в руке у него на бумажке написано ты номер 1. Он встал и пошел дальше. Пойти то пошел, да на его месте опять же этот человек лежит. А у него в руке бумажка, на которой написано ты номер 2. Этот человек поднялся, подумал, что сейчас вот зайду за другой угол, а там опять кирпичом по голове дадут, и пошел в другую сторону.

Так вот, вернемся к нашим баранам. Одному процессу достается значение, идентифицирующее порожденный процесс. То есть, дописываем в бумажку первого человека фразу типа "у второго номер 2". Это бывает необходимым, в случае если подразумевается