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