14.1.3. Манипулирование процессами

14.1.3. Манипулирование процессами

В этом разделе мы обсудим манипулирование процессами, хотя создание нового процесса необязательно связано с запуском внешней программы. Основной способ создания нового процесса — это метод fork, название которого в соответствии с традицией UNIX подразумевает разветвление пути исполнения, напоминая развилку на дороге. (Отметим, что в базовом дистрибутиве Ruby метод fork на платформе Windows не поддерживается.)

Метод fork, находящийся в модуле Kernel (а также в модуле Process), не следует путать с одноименным методом экземпляра в классе Thread.

Существуют два способа вызвать метод fork. Первый похож на то, как это обычно делается в UNIX, — вызвать и проверить возвращенное значение. Если оно равно nil, мы находимся в дочернем процессе, в противном случае — в родительском. Родительскому процессу возвращается идентификатор дочернего процесса (pid).

pid = fork

if (pid == nil)

 puts "Ага, я, должно быть, потомок."

 puts "Так и буду себя вести."

else

 puts "Я родитель."

 puts "Пора отказаться от детских штучек."

end

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

Следует также отметить, что процесс-потомок может пережить своего родителя. Для потоков в Ruby это не так, но системные процессы — совсем другое дело.

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

fork do

 puts "Ага, я, должно быть, потомок."

 puts "Так и буду себя вести."

end

puts "Я родитель."

puts "Пора отказаться от детских штучек."

Конечно, pid по-прежнему возвращается, мы просто не показали его.

Чтобы дождаться завершения процесса, мы можем вызвать метод wait из модуля Process. Он ждет завершения любого потомка и возвращает его идентификатор. Метод wait2 ведет себя аналогично, только возвращает массив, содержащий РМ, и сдвинутый влево код завершения.

Pid1 = fork { sleep 5; exit 3 }

Pid2 = fork { sleep 2; exit 3 }

Process.wait  # Возвращает pid2

Process.wait2 # Возвращает [pid1,768]

Чтобы дождаться завершения конкретного потомка, применяются методы waitpid и waitpid2.

pid3 = fork { sleep 5; exit 3 }

pid4 = fork { sleep 2; exit 3 }

Process.waitpid(pid4,Process::WNOHANG)   # Возвращает pid4

Process.waitpid2(pid3, Process::WNOHANG) # Возвращает [pid3,768]

Если второй параметр не задан, то вызов может блокировать программу (если такого потомка не существует). Второй параметр можно с помощью ИЛИ объединить с флагом Process::WUNTRACED, чтобы перехватывать остановленные процессы. Этот параметр системно зависим, поэкспериментируйте.

Метод exit! немедленно завершает процесс (не вызывая зарегистрированных обработчиков). Если задан целочисленный аргумент, то он возвращается в качестве кода завершения; по умолчанию подразумевается значение 1 (не 0).

pid1 = fork { exit! }   # Вернуть код завершения -1.

pid2 = fork { exit! 0 } # Вернуть код завершения 0.

Методы pid и ppid возвращают соответственно идентификатор текущего и родительского процессов.

proc1 = Process.pid

fork do

 if Process.ppid == proc1

  puts "proc1 - мой родитель" # Печатается это сообщение.

 else

  puts "Что происходит?"

 end

end

Метод kill служит для отправки процессу сигнала, как это понимается в UNIX. Первый параметр может быть целым числом, именем POSIX-сигнала с префиксом SIG или именем сигнала без префикса. Второй параметр — идентификатор процесса-получателя; если он равен нулю, подразумевается текущий процесс.

Process.kill(1,pid1)        # Послать сигнал 1 процессу pid1.

Process.kill ("HUP",pid2)   # Послать SIGHUP процессу pid2..

Process.kill("SIGHUP",pid2) # Послать SIGHUP процессу pid3.

Process.kill("SIGHUP",0)    # Послать SIGHUP самому себе.

Для обработки сигналов применяется метод Kernel.trap. Обычно он принимает номер или имя сигнала и подлежащий выполнению блок.

trap(1) { puts "Перехвачен сигнал 1" }

sleep 2

Process.kill(1,0) # Послать самому себе.

О применениях метода trap в более сложных ситуациях читайте в документации по Ruby и UNIX.

В модуле Process есть также методы для опроса и установки таких атрибутов процесса, как идентификатор пользователя, действующий идентификатор пользователя, приоритет и т.д. Дополнительную информацию вы отыщете в справочном руководстве по Ruby.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Манипулирование шрифтами

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Манипулирование шрифтами Теперь давайте выясним, как можно программно манипулировать шрифтами. Тип System.Drawing.Font представляет шрифт, установленный на машине пользователя, Типы шрифта могут определяться с помощью любого числа перегруженных конструкторов. Вот вам


Манипулирование данными с помощью объектов

Из книги Обработка баз данных на Visual Basic®.NET автора Мак-Манус Джеффри П

Манипулирование данными с помощью объектов После создания таблиц можно приступить к манипуляциям с данными: вводить данные в таблицы, извлекать их из таблиц, проверять и изменять структуру таблиц. Для манипулирования структурой таблиц используются команды определения


Манипулирование данными с помощью SQL

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

Манипулирование данными с помощью SQL Команда манипулирования данными (data manipulation command) — это команда SQL, которая изменяет записи. Такие команды создаются на языке манипулирования данными DML, который является подмножеством языка SQL. Эти команды не возвращают записи, а


7.14. Манипулирование временем без даты

Из книги Справочник по PHP автора

7.14. Манипулирование временем без даты Иногда нужно работать с временем дня в виде строки. На помощь снова приходит метод strftime. Можно «разбить» время на часы, минуты и секундыt = Time.nowputs t.strftime("%H:%M:%S") # Печатается 22:07:45А можно только на часы и минуты (прибавив 30 секунд, мы даже


10.1.17. Манипулирование путевыми именами

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

10.1.17. Манипулирование путевыми именами Основными методами для работы с путевыми именами являются методы класса File.dirname и File.basename; они работают, как одноименные команды UNIX, то есть возвращают имя каталога и имя файла соответственно. Если вторым параметром методу basename


10.1.19. Манипулирование файлами на уровне команд

Из книги C++. Сборник рецептов автора Диггинс Кристофер

10.1.19. Манипулирование файлами на уровне команд Часто приходится манипулировать файлами так, как это делается с помощью командной строки: копировать, удалять, переименовывать и т.д.Многие из этих операций реализованы встроенными методами, некоторые находятся в модуле


13.1. Создание потоков и манипулирование ими

Из книги Разработка ядра Linux автора Лав Роберт

13.1. Создание потоков и манипулирование ими К числу основных операций над потоками относятся создание потока, передача ему входной информации и получение результатов, останов потока и т.д. Можно получить список запущенных потоков, опросить состояние потока и выполнить


Манипулирование каталогами

Из книги Linux Mint и его Cinnamon. Очерки применителя автора Федорчук Алексей Викторович

Манипулирование каталогами mkdirСоздание каталога.Синтаксис:bool mkdir(string $name, int $perms)Создает каталог с именем $name и правами доступа perms. Права доступа для каталогов указываются точно так же, как и для файлов. Чаще всего значение $perms устанавливают равным 0770 (предваряющий ноль


Манипулирование изображениями

Из книги автора

Манипулирование изображениями imageCreateСоздание пустой картинки.Синтаксис:int imageCreate(int x, int y)Создает пустую картинку размером x на y точек и возвращает ее идентификатор. После того, как картинка создана, вся работа с ней осуществляется именно через этот идентификатор, по


11.4. Манипулирование содержимым каталогов

Из книги автора

11.4. Манипулирование содержимым каталогов Вспомните, что компоненты каталогов (имена файлов) — это ни что иное, как указатели на дисковые информационные узлы (on-disk inodes); почти вся важная информация, касающаяся файла, хранится в его inode. Вызов open() позволяет процессу


12.2.4. Манипулирование маской сигналов процесса

Из книги автора

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


17.8.1. Манипулирование IPv4-адресами

Из книги автора

17.8.1. Манипулирование IPv4-адресами Функции inet_ntop() и inet_pton() являются относительно новыми и были введены для того, чтобы один набор функций мог обрабатывать и IPv4-, и IPv6-адреса. До их появления в программах использовались функции inet_addr(), inet_aton() и inet_ntoa(), которые предназначены


Манипулирование файлами

Из книги автора

Манипулирование файлами Перейдем к манипуляциям с существующими файлами — копированию, перемещёнию, переименованию, удалению.Начнем с копирования — это выполняется очень простой командой, cp, имеющей, однако, весьма разнообразные аспекты применения. В самом простом