2015-10-15 4 views
8

Я понимаю, что cPython имеет GIL, так что ваш скрипт не может работать на нескольких ядрах без использования модуля многопроцессорности. Но есть ли что-нибудь, чтобы остановить встроенные функции, такие как сортировка с использованием нескольких ядер? Я не понимаю структуру cPython, но я думаю, что вопрос, который я задаю, это «встроенные функции, такие как сортировка, какие-либо и списки на самом деле ниже GIL?Использует ли cPython несколько ядер для встроенных функций, таких как sort, any, all?

ответ

5

cPython GIL имеет отношение только к одному потоку для запуска байт-кода в процессе - это не связано с не-абстрактным ЦП.

Сказанное, если только вы не вызываете что-то в fork/используете несколько процессов, или ваша ОС/оборудование ловит вызовы и делает это для вас (крайне маловероятно), вы увидите, что все ваши операции происходят на одноядерное ядро.

Встроенные функции, реализованные в C, происходят «под GIL», поскольку они являются более прямыми вызовами для базовых API-интерфейсов, но ввод данных в эти функции происходит в GIL, поскольку вы используете байт-код для прочти и напиши.

Как в стороне, если вы хотите лучше понять отношения cPython с его хостом, я бы предложил следующие high-level official overview и/или the PDF slides and the playground that I wrote for a conference.

+0

GIL - это не только байтовый код. Количество ссылок также должно обновляться только под GIL, что означает, что материал, который манипулирует подсчетами ссылок вообще, не может освободить GIL, когда он это делает. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' полностью за GIL, потому что во всех случаях происходит много манипуляций счетчика ссылок, даже если байт-код не обязательно выполняется (например, в случае 'sorted' using встроенные типы, где сравнения также находятся на слое С). Были проведены тесты использования атомных операций для поддержания значений ref, и это всегда замедлило CPython неприемлемо. – ShadowRanger

+1

Я не уверен, что я заявил, что GIL _only_ имеет отношение к байт-коду - я обращался к вопросу о «переднем конце» Python - sort/any/list. Передача аргументов в них происходит в байтовом коде. –

+0

Вы не сделали этого, но основной вопрос, препятствующий использованию 'sorted' /' any'/'all' от выпуска GIL (даже если бы они могли гарантировать, что обрабатываемые элементы никогда не исполняются байтовым кодом для сравнения, генерируя значения , применение предикатов и т. д.). Вопрос OP состоял в умении распараллеливать и ограничения GIL, а не в том, что такое байтовый код, а что нет. Встроенные компоненты находятся ниже уровня байтового кода, но они не свободны от GIL, потому что даже если работа, которую они сделали, может быть гарантирована никогда не исполнять байтовый код (он не может), даже код целиком на C с использованием объектов Python нуждается в GIL. – ShadowRanger

2

Ни одна из функций, которые вы упомянули, не разглашается автоматически. В общем, тихонезлые нити считаются плохой формой на большинстве языков (это меняется, но это все еще видно только на чистых функциональных языках, где безопасность потоков выпекается по дизайну); нереста много потоков без предупреждения - это то, как вы получаете таинственные ошибки, когда пользователь пытается запустить свои собственные потоки и получить временные ошибки из-за слишком большого количества потоков. Так что, даже если бы GIL не был проблемой, это не имело бы смысла делать это.

Это означает, что GIL защищает внутренности интерпретатора и охватывает любой сценарий, в котором манипулируют счетчики ссылок, которые постоянно; за редким исключением, невозможно сделать какую-либо значимую работу на PyObject* (это то, что все типы уровня Python представлены как на C) с сохраненным GIL. Как правило, встроенные модули Python выпускают только GIL для операций блокировки (ввод-вывод, ожидание блокировок и т. Д.); это только в сторонних расширениях C (и ctypes), где выпуск GIL является нормальным, потому что в этих случаях они полностью конвертируют PyObject s в типы уровней C, освобождают GIL теперь, когда не происходит никакого подсчета ссылок или других внутренних элементов, выполните дорогостоящую работу, повторно получить GIL и преобразовать результаты с типов уровня C в объекты уровня Python.