Найти - Пользователи
Полная версия: Особенности организации множества потоков
Начало » Python для экспертов » Особенности организации множества потоков
1 2 3 4
Андрей Светлов
Kogrom прав. Создается множество потоков, но в одно время работает только один.
Я как-то потрудился это все детально описать: http://asvetlov.blogspot.com/2011/07/gil.html
Вопросы?
XCoder
Я извиняюсь, за вопрос не относящийся непосредственно к многопоточности на уровне процессов/потоков конкретного алгоритма:

Если учесть, что в классическом варианте отработка скрипта это интерпретирование, а затем транслирование кода, то как будет срабатывать сам интерпретатор при практически параллельных запросах?

То есть, допустим, время интерпретации / трансляции кода составляет 100 мкс для одного и того же скрипта. И в этот интервал времени происходит 10 обращений на исполнение с интервалом в 10 мкс.

Сам интерпретатор Python будет динамически распределять внутри своих потоков на все доступные процессоры (ядра) задачи интерпретации / трансляции кода?

Или же интерпретатор работает в рамках нескольких потоков одного собственного процесса только на одном процессоре (ядре) ?
Александр Кошелев
XCoder
Если учесть, что в классическом варианте отработка скрипта это интерпретирование, а затем транслирование кода, то как будет срабатывать сам интерпретатор при практически параллельных запросах?
Подождите, что такое “транслирование” кода? Интерпретатор только интерпретирует код скрипта.
Isem
Александр Кошелев
Подождите, что такое “транслирование” кода? Интерпретатор только интерпретирует код скрипта.
Интерпретатор интерпретирует - это значит транслирует и выполняет. А транслирует он ее в код виртуальной машины, именуемым байт-кодом. Что интерпретатор, что компилятор - оба они трансляторы. Сделайте из виртуальной машины физическую, - и интерпретатор чудным образом превратится в компилятор.
XCoder
Сам интерпретатор Python будет динамически распределять внутри своих потоков на все доступные процессоры (ядра) задачи интерпретации / трансляции кода?
Этим занимается ОС. Python (как процесс) лишь может самостоятельно регулировать количество своих собственных исполняемых потоков и самостоятельно же их синхронизировать. Один и тот же поток может какое то время выполняться на одном процессоре, затем на другом, потом на третьем, и только ОС этим заведует.
XCoder
Александр Кошелев
Подождите, что такое “транслирование” кода? Интерпретатор только интерпретирует код скрипта.
Я имел в виду интерпретацию кода в байт-код (сырой код -> байт-код) и внутреннее транслирование уже на уровне виртуальной машины в инструкции (байт-код -> инструкции), которые исполняются (инструкции -> Profit =) ).

Isem
Этим занимается ОС. Python (как процесс) лишь может самостоятельно регулировать количество своих собственных исполняемых потоков и самостоятельно же их синхронизировать.
То, что поточностью управляет ОС понятно, но ведь синхронизация лежит на процессе интерпретатора.

Просто возникла мысль, не поставит ли интерпретатор задачу собственно интерпретирования в очередь. Иными словами, на самом факте ожидания интерпретации можно потерять уйму времени при большом количестве “одновременных” обращений.

То есть будет ли один процесс многопоточного интерпретатора Python порождать такое количество потоков, сколько это требуется для одновременной интерпретации различных кодов, или же потоками он забьет одно ядро (ОС, разумеется, при этом будет честно отрабатывать планирование прерываний)?

Если допустить, что в сервере 16 ядер и (условно) крайне эффективный доступ к файловой системе (допустим RAM-диск), то сможет ли интерпретатор загрузить все 16 ядер одновременно для интерпретирования и исполнения в своих потоках 16 скриптов?
Isem
XCoder
Если допустить, что в сервере 16 ядер и (условно) крайне эффективный доступ к файловой системе (допустим RAM-диск), то сможет ли интерпретатор загрузить все 16 ядер одновременно для интерпретирования и исполнения в своих потоках 16 скриптов?
Конечно сможет, если он создает нитки (потоки) и не блокирует их сам.
Андрей Светлов
Не вполне уловил вопрос.
Питон создает code objects (байткод) при импорте модуля. Если кеш (.pyc файл) свежей исходника (.py) — грузится из кеша.
В любом случае никаких дополнительный потоков не создается, трансляция исходника в байткод — синхронная операция.
Более того, выставляется блок, запрещающий одновременный импорт из нескольких потоков. Так нужно.

Одни процесс питона 16 ядер не загрузит (маленькая оговорка: если этот процесс не использует интенсивно CPU затратные C Extensions, надолго отпускающие GIL во время вычислений — крайне редкий случай).
XCoder
Андрей Светлов
Одни процесс питона 16 ядер не загрузит
Я имею в виду не интерпретирование одного кода в 16 потоков, а интерпретирование 16-ти независимых кодов в отдельных потоках в рамках процесса интерпретатора.

Допустим, 16 файлов с байт-кодом:
P1.pyc
P2.pyc

P16.pyc

Какова будет картина происходящего, если практически одновременно произойдут обращения к этим скриптам?

Я никак не могу понять, процесс интерпретатора сможет запустить одновременно взаимонезависимые операции исполнения байт-кода на 16 ядер или он будет поочередно обрабатывать их с учетом GIL?



Попробую изобразить случай первый (16 независимых потоков) за единый интервал времени t:
P1.pyc -> Core 1 -> exec; - на исполнение требуется время равное t
P2.pyc -> Core 2 -> exec; - на исполнение требуется время равное t
P3.pyc -> Core 3 -> exec; …

P16.pyc -> Core 16 -> exec;

В итоге все процессы выполняться за время близкое к времени t.



Или же все будет иначе, случай второй, исполнение поочередно:
P1.pyc -> Core 1 -> exec, P2.pyc -> Core 2 -> exec, … , P16.pyc -> Core 16 -> exec;

В итоге все процессы выполняться за время близкое ко времени



Просто это нюанс, который мне не совсем ясен.

Так, в частности, если бы мы запустили 16 независимых процессов интерпретатора (заняв в 16 раз больше памяти), то и вопросов не возникло бы, так как они независимы по определению.

Но ведь интерпретатор запускает потоки, насколько я понимаю. Т.е. интерпретатор же не вызывает fork самого себя для отработки параллельных операций. И, с одной стороны, ОС, управляя потоками может их распределять по всем ядрам, загружая их все работой, но с другой стороны поток, это не процесс и за всю синхронизацию отвечает процесс, которому принадлежит совокупность исполняемых потоков. Собственно в этом и вся прелесть потоков, опять же насколько я понимаю, т.к. они не требуют излишнего количества системных операций, которые тоже кушают процессорное время.

Так где же истина?

Если писать многопоточное (многозадачное) приложение, то, я считаю, важно понять этот аспект, в противном случае, сотни запущенных в обработку потоков, которые должны экономить ресурсы, будут просто транжирить процессорное время и в соотношении “время исполнения / память” система не будет иметь совершенно никакого смысла.

Собственно, я уперся, решая ту же проблему в рамках интерпретатора/транслятора РНР в ограничения на уровне языка: то есть в РНР попросту не существует понятия поток, есть лишь костыльный способ вызывать fork(), но при этом возникает чрезмерное потребление памяти в соотношении с эффективными размерами кода.

Это и привело меня к Python, как весьма неплохой альтернативе для Web-программирования. К тому же в ряде тестов скрипты на нем более эффективно работают с операциями I/O. Но в том изначально и была суть вопроса, он подойдет или нет? Чтобы мне снова не упереться, но уже в ограничения реализации интерпретатора питона.
Lexander
Все таки нужна конкретизация задачи.
Потоки и процессы решают схожие, но разные задачи.
Разное назначение дает разную реализацию.

Уже читали http://proft.me/2010/11/7/parallelizm-v-python/ ?
doza_and
XCoder
Чтобы мне снова не упереться, но уже в ограничения реализации интерпретатора питона
Не упретесь, по крайней мере в этом месте. У вас есть multiprocessing на крайний случай
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB