Почему статические переменные в xsub не являются потокобезопасными? - PullRequest
0 голосов
/ 13 ноября 2018

Согласно perldoc threads:

Начиная с Perl 5.8, доступно программирование потоков с использованием модели, называемой потоками интерпретатора, которая предоставляет новый интерпретатор Perl для каждого потока, ипо умолчанию не приводит к обмену данными или информацией о состоянии между потоками.

Какой тип информации data или state упоминается в приведенной выше цитате?В соответствии с perldoc perlxs:

Начиная с Perl 5.8, определена макро-среда, позволяющая безопасно хранить статические данные в модулях XS, к которым будет обращаться из несколькихPerl.

Так что мне кажется, что статические переменные совместно используются потоками?Но Perl переменные не являются общими?(Я пытаюсь выяснить, какие именно данные являются потокобезопасными, и как создать потокобезопасный модуль)

1 Ответ

0 голосов
/ 13 ноября 2018

У каждого потока есть свой интерпретатор. Эта структура [1] хранит все, что составляет perl, включая состояние синтаксического анализатора, состояние обработчика регулярных выражений, таблицу символов и все "SV" (включая скаляры, массивы, хэши, код и т. Д.). ). Создание нового потока из копий Perl создает копию текущего интерпретатора.

Код XS может безопасно использовать Perl API, потому что у каждой функции есть параметр, который определяет интерпретатор для использования. Это часто невидимо для кода благодаря макросам, но вы могли заметить ссылки на «THX» или «контекст Perl». Только не передавайте SV, который принадлежит одному переводчику другому. (Возможно, вы слышали об ошибке «Свободный в неправильный пул», которая может появиться в результате.)

Но Perl не может предложить никакой защиты вещам, находящимся вне его знаний или контроля, таких как статическое хранилище внешних библиотек, которые он загружает. Их копии не сделаны. Два потока могут вызывать одну и ту же функцию C одновременно, поэтому необходимо соблюдать меры предосторожности, как если бы вы писали многопоточную программу на C.

Эта структура макроса, на которую ссылается ваша цитата, дает доступ к хранилищу для каждого переводчика. Это также позволяет библиотеке указывать функцию для вызова при создании новых потоков Perl для клонирования переменных в новый интерпретатор.


  1. Если Perl создается без -Dusemultiplicity, интерпретатор Perl вместо этого состоит из глобальных (статических) переменных bajillion. MULTIPLICITY перемещает их в структуру и добавляет параметр контекста к вызовам API Perl. Это снижает производительность, но позволяет процессу иметь несколько интерпретаторов Perl. Поскольку для многопоточных сборок Perl требуется это, сборка многопоточных perl (-Dusethreads) предполагает -Dusemultiplicity.
...