Почему статические переменные в xsub не являются потокобезопасными?

В соответствии с perldoc threads:

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

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

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

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

1 ответ

Решение

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

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

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

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


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