Поток
СОДЕРЖАНИЕ
НАЗВАНИЕ
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
-
Возвращает список всех объектов потока, которые не объединены и не отсоединены.
- 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–2021 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.36.0/Thread