Чтение онлайн

на главную - закладки

Жанры

Язык программирования Perl
Шрифт:

Рис. 16.1.Полновесные процессы и нити (потоки управления)

Существует несколько моделей многопоточной обработки, например DEC, Java, POSIX, Win32. Perl предлагает свою модель многопоточного программирования, отличающуюся от перечисленных и имеющую свои достоинства и недостатки. Появление в Perl кросс-платформенных средств работы с легковесными процессами стало несомненным достижением, которое заставило по-новому взглянуть на программирование параллельных процессов. Применение легковесных процессов позволяет разрабатывать эффективные приложения, одинаково выполняющиеся на разных платформах.

Работать с легковесными процессами просто. Подключив средства работы с нитями прагмой use threads, можно создать нить с помощью метода threads->new (синоним: threads->create). Этому методу передается ссылка на именованную или анонимную подпрограмму, которая запускается на выполнение в виде параллельного потока управления. Результатом создания нити станет ссылка на объект типа threads, который будет использоваться для управления потоком. Создание нити выглядит так:

use threads; # подключить многопоточные средства

my $thread = threads->new(\&pearl_thread); # запустить нить

sub pearl_thread { # эта подпрограмма

print "Это нить.\n"; # будет выполняться как нить

} #

Итак, в определенной точке программы нить начала выполняться параллельно действиям в основной программе. Куда же должен произойти возврат, когда нить завершится? Это задается в основной программе с помощью метода join, который приостанавливает работу программы до завершения выполнения нити и возвращает результат, вычисленный нитью:

@result = $thread->join;

Действие, выполняемое методом join, называется "присоединение нити" или "объединение потоков". Как это происходит, показано на рис. 16.2.

Рис. 16.2.Присоединение нити с помощью join

Каждой нити присваивается числовой идентификатор (Thread Identifier, TID), который можно получить с помощью метода tid. Создание нескольких нитей, объединение потоков и возврат значений из параллельно выполняющихся подпрограмм можно показать на таком примере:

use threads; # подключить многопоточные средства

my @thread = ; # массив объектов типа threads

for (my $i = 0; $i <= 2; $i++) { # создаем 3 нити

$thread[$i] = threads->new(\&pearl_thread, $i);

print "Создана $i-я нить. TID=", $thread[$i]->tid, "\n";

}

for (my $i = 2; $i >= 0; $i--) { # присоединяем нити

print "$i-я нить вернула ", $thread[$i]->join, "\n";

}

sub pearl_thread ($) { # нить получает

my $number = shift; # число, генерирует

my $random = int(rand(7)) + 1; # случайное значение,

print "\t$number-я нить ждет $random сек.\n";

sleep $random; # и, подождав немного,

return $random; # возвращает его

}

Сообщения, выводимые при выполнении этой программы, подтверждают независимое выполнение нитей и основной программы:

Создана 0-я нить. TID=1

Создана 1-я нить. TID=2

1-я нить ждет 7 сек.

0-я нить ждет 1 сек.

Создана 2-я нить. TID=3

2-я нить ждет 3 сек.

2-я нить вернула 3

1-я нить вернула 7

0-я нить вернула 1

Параллельно выполняющийся поток можно "отсоединить", игнорируя его значение: это делается методом $thread->detach, после выполнения которого присоединить нить будет невозможно.

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

use threads; # подключить многопоточные средства

use threads::shared; # и средства разделения данных

my $public : shared = 0; # разделяемая переменная

my $private = 0; # неразделяемая переменная

threads->new(sub { # нить из анонимной подпрограммы

$public++; $private++; # изменяем значения

print "$public $private\n"; # будет выведено: 1 1

})->join; # дожидаемся результатов выполнения:

print "$public ", # 1 ($public изменена в нити)

"$private\n"; # 0 (в нити изменена копия $private)

Чтобы предотвратить в одной нити изменение другими нитями значения разделяемой переменной, эту переменную нужно заблокировать при помощи функции lock. Разблокирование переменной происходит не с помощью функции, а при выходе из блока, в котором она была заблокирована. Это делается таким образом:

{ # блок для работы с разделяемой переменной

Поделиться:
Популярные книги

Неучтенный элемент. Том 10

NikL
10. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 10

Русская драматургия XVIII – XIX вв. (Сборник)

Пушкин Александр Сергеевич
Поэзия:
драматургия
6.25
рейтинг книги
Русская драматургия XVIII – XIX вв. (Сборник)

Хранилище

Старухин Евгений
5. Лесовик
Фантастика:
фэнтези
рпг
7.43
рейтинг книги
Хранилище

Газлайтер. Том 18

Володин Григорий Григорьевич
18. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 18

В лапах зверя

Зайцева Мария
1. Звериные повадки Симоновых
Любовные романы:
остросюжетные любовные романы
эро литература
5.00
рейтинг книги
В лапах зверя

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Гримуар тёмного лорда I

Грехов Тимофей
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар тёмного лорда I

Изгой Проклятого Клана. Том 2

Пламенев Владимир
2. Изгой
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Изгой Проклятого Клана. Том 2

Кодекс Охотника. Книга XXXII

Винокуров Юрий
32. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXXII

Черный Маг Императора 10

Герда Александр
10. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 10

Ваше Сиятельство 7

Моури Эрли
7. Ваше Сиятельство
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Ваше Сиятельство 7

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII

Слово мастера

Лисина Александра
11. Гибрид
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Слово мастера

Законы рода

Мельник Андрей
1. Граф Берестьев
Фантастика:
фэнтези
боевая фантастика
аниме
5.00
рейтинг книги
Законы рода