Поток
СОДЕРЖАНИЕ
НАЗВАНИЕ
Поток - Управление потоками в 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 равен нулю, а последующим потокам присваиваются tid, начиная с единицы. - 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.28.3/Thread