Поток
СОДЕРЖАНИЕ
НАЗВАНИЕ
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–2023 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.38.0/Thread