Spec-Zone.ru › Perl 5.32

Поток

СОДЕРЖАНИЕ

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

ИМЯ

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–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.32.0/Thread

Spec-Zone.ru

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