Поток
СОДЕРЖАНИЕ
ИМЯ
Thread - Управление потоками в Perl (только для старого кода)
УСТАРЕЛО
Модуль Thread служил передним фронтом для модели потоков старого стиля, называемой 5005threads, которая была представлена в релизе 5.005. Эта модель была устаревшей и удалена в версии 5.10.
Для старого кода и временной обратной совместимости модуль Thread был переработан, чтобы функционировать как интерфейс для новой модели интерпретируемых потоков (ithreads). Однако некоторые предыдущие функции недоступны. Кроме того, модели совместного использования данных между двумя моделями потоков совершенно разные, и всё, что связано с совместным доступом к данным, должно рассматриваться иначе. С ithreads вы должны явно share() переменные между потоками.
Настоятельно рекомендуется как можно скорее мигрировать любой существующий потоковый код в новую модель (т.е. использовать модули threads и threads::shared).
ИСТОРИЯ
В Perl 5.005 модель потоков была такой, что все данные неявно разделяются, и совместный доступ к данным необходимо явным образом синхронизировать. Эта модель называется 5005threads.
В Perl 5.6 была представлена новая модель, в которой всё было локально для потока, а совместный доступ к данным необходимо было явно объявлять. Эта модель называется ithreads, что означает "интерпретируемые потоки".
В Perl 5.6 модель ithreads была недоступна как публичный API; только как внутренний API, доступный для разработчиков расширений и для реализации эмуляции fork() на платформах Win32.
В Perl 5.8 модель ithreads стала доступна через модуль threads, а модель 5005threads была устаревшей.
В Perl 5.10 модель 5005threads была удалена из интерпретатора Perl.
СИНОПСИС
use Thread qw(:DEFAULT async yield);
my $t = Thread->new(\&start_sub, @start_args);
$result = $t->join;
$t->detach;
if ($t->done) {
$t->join;
}
if($t->equal($another_thread)) {
# ...
}
yield();
my $tid = Thread->self->tid;
lock($scalar);
lock(@array);
lock(%hash);
my @list = Thread->list; ОПИСАНИЕ
Модуль Thread обеспечивает поддержку многопоточности для Perl.
ФУНКЦИИ
- $thread = Thread->new(\&start_sub)
- $thread = Thread->new(\&start_sub, LIST)
-
newзапускает новый поток выполнения в указанной подпрограмме. Необязательный список передаётся как параметры в подпрограмму. Выполнение продолжается как в подпрограмме, так и в коде после вызоваnew.Thread->newвозвращает объект потока, представляющий вновь созданный поток. - lock VARIABLE
-
lockблокирует переменную до выхода из области видимости блокировки.Если переменная заблокирована другим потоком, вызов
lockзаблокируется до тех пор, пока она не станет доступной.lockрекурсивная, поэтому несколько вызововlockбезопасны — переменная останется заблокированной до выхода из области видимости самой внешней блокировки переменной.Блокировки переменных влияют только на вызовы
lock— они не влияют на обычный доступ к переменной. (Блокировки подпрограмм отличаются и описаны немного позже). Если вы действительно, действительно хотите, чтобы блокировки блокировали доступ, тогда привяжите их к чему-нибудь и управляйте этим сами. Это сделано намеренно. Хотя управление доступом к переменным — это хорошо, Perl не выгоняет вас из гостиной...Если объект контейнера, такого как хэш или массив, заблокирован, все элементы этого контейнера не блокируются. Например, если поток выполняет
lock @a, любой другой поток, выполняющийlock($a[12]), не заблокируется.Наконец,
lockпереходит по ссылкам ровно на один уровень.lock(\$a)эквивалентноlock($a), в то время какlock(\\$a)нет. - async BLOCK;
-
asyncсоздаёт поток для немедленного выполнения блока, следующего за ним. Этот блок рассматривается как анонимная подпрограмма, поэтому после закрывающей фигурной скобки должен стоять точка с запятой. Как иThread->new,asyncвозвращает объект потока. - Thread->self
-
Функция
Thread->selfвозвращает объект потока, представляющий поток, сделавший вызовThread->self. - Thread->list
-
Возвращает список всех не объединённых, не отсоединённых объектов Thread.
- cond_wait VARIABLE
-
Функция
cond_waitпринимает заблокированную переменную в качестве параметра, разблокирует переменную и блокируется до тех пор, пока другой поток не выполнитcond_signalилиcond_broadcastдля той же заблокированной переменной. Переменная, на которойcond_waitзаблокировался, снова блокируется после того, как выполнениеcond_waitудовлетворено. Если несколько потоковcond_waitна одной и той же переменной, все, кроме одного, снова заблокируются, ожидая повторного получения блокировки на переменной. (Поэтому если вы используетеcond_waitтолько для синхронизации, освободите блокировку как можно быстрее). - cond_signal VARIABLE
-
Функция
cond_signalпринимает заблокированную переменную в качестве параметра и разблокирует один поток, который выполняетcond_waitна этой переменной. Если более одного потока заблокированы вcond_waitна этой переменной, только один (и какой именно — неопределённо) будет разблокирован.Если нет потоков, заблокированных в
cond_waitна переменной, сигнал игнорируется. - cond_broadcast VARIABLE
-
Функция
cond_broadcastработает аналогичноcond_signal.cond_broadcast, однако, разблокирует все потоки, заблокированные вcond_waitна заблокированной переменной, а не только один. - yield
-
Функция
yieldпозволяет другому потоку взять контроль над процессором. Точные результаты зависят от реализации.
МЕТОДЫ
- join
-
joinожидает завершения потока и возвращает любые значения, с которыми поток завершился.joinбудет заблокирован до завершения потока, хотя не заблокируется, если поток уже завершился.Если поток, на котором выполнялось
join,dieлся, ошибка, с которой он умер, будет возвращена в этот момент. Если вы не хотите, чтобы поток, выполняющийjoin, также умер, вы должны либо обернутьjoinвeval, либо использовать метод потокаevalвместоjoin. - detach
-
detachсообщает потоку, что он никогда не будет объединён, т.е. что все следы его существования можно удалить, как только он перестанет работать. Ошибки в отсоединённых потоках нигде не будут видны — если вы хотите их перехватить, вы должны использовать $SIG{__DIE__} или что-то подобное. - equal
-
equalпроверяет, представляют ли два объекта потока один и тот же поток, и возвращает true, если это так. - tid
-
Метод
tidвозвращает tid потока. Tid — это монотонно возрастающее целое число, присваиваемое при создании потока. Главный поток программы будет иметь tid 0, в то время как последующие потоки будут иметь tid, начиная с 1. - done
-
Метод
doneвозвращает true, если поток, который вы проверяете, завершён, и false в противном случае.
УДАЛЕННЫЕ
Следующие функции были реализованы с помощью 5005threads, но больше не доступны с ithreads.
- lock(\&sub)
-
С помощью 5005threads можно также
lockподпрограмму, таким образом, любые вызовы этой подпрограммы из другого потока будут блокироваться до тех пор, пока блокировка не будет освобождена.Также подпрограммы могли быть объявлены с атрибутом
:locked, что сериализовало доступ к подпрограмме, но позволяло разным потокам неодновременный доступ. - eval
-
Метод
evalобернулevalвокругjoin, и поэтому ожидал завершения потока, передавая любые значения, которые мог вернуть поток, и помещая любые ошибки в$@. - flags
-
Метод
flagsвозвращал флаги потока — целочисленное значение, соответствующее внутренним флагам потока.
СМОТРИТЕ ТАКЖЕ
threads, threads::shared, Thread::Queue, Thread::Semaphore
© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.32.0/Thread