Spec-Zone.ru › Perl 5.36

Поток

СОДЕРЖАНИЕ

  • НАЗВАНИЕ
  • УСТАРЕЛО
  • ИСТОРИЯ
  • СИНОПСИС
  • ОПИСАНИЕ
  • ФУНКЦИИ
  • МЕТОДЫ
  • УДАЛЕННЫЕ
  • СМОТРИТЕ ТАКЖЕ

НАЗВАНИЕ

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API