Spec-Zone.ru › Perl 5.28

Поток

СОДЕРЖАНИЕ

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

НАЗВАНИЕ

Поток - Управление потоками в 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

Spec-Zone.ru

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