Могу ли я обойти Python GIL с помощью модуля C? - PullRequest
2 голосов
/ 19 февраля 2012

Я думал провести эксперимент с питоном. Я хотел бы представить некоторые функции, такие как набор JavaScript javascript setTimeout или setInterval, портирующий какое-то асинхронное поведение без большого количества блокирующих вызовов для запуска цикла обработки событий.

Давайте посмотрим на этот пример (теперь, конечно, не работает):

from mymod import set_timeout # of course we love the PEP8 :)
import sys, time

def say_finished():
    time.sleep(2) # waiting, suppose here to have some blocking behaviour
    sys.stdout.write("\nSee you!")

sys.stdout.write("Hello, ")
set_timeout(say_finished, 2000) # supposing we have msec granularity
sys.stdout.write("World!")

Я бы хотел вести себя так, как это делает JavaScript. Если set_timeout запускает новый поток из-за GIL, он все равно выдает «Hello, \ nSee you! World», потому что новый поток блокирует основной поток до его завершения.

Смогу ли я обойти это поведение, если set_timeout будет использовать потоки posix в коде C? Это будет интеграция с Python C / API, и я не знаю, смогу ли я обойти GIL или сам GIL также будет вынужден блокировать GIL (я бы попробовал, но сейчас я изучаю документы, и я не готов попробовать это сам).

Это должно быть так: вывести «Hello» -> запустить set_timeout (которое должно вернуться, чтобы интерпретатор мог продолжить выполнение программы) -> напечатать «World!» -> остаться в живых, пока работает внешний поток -> обратный вызов "say_finished" -> end.

То, что заставляет меня думать, что для редактирования самого интерпретатора потребуется, - это часть, в которой говорится «оставайтесь в живых, пока работает внешний поток».

Я не хочу использовать процессы из-за накладных расходов, которые создает новый процесс.

Пожалуйста, не говорите «тогда используйте Javascript», потому что мне нравится синтаксис Python, и я хотел бы использовать этот подход с ним.

1 Ответ

2 голосов
/ 19 февраля 2012

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

Вы можете запускать код более чем заодин поток, использующий модуль threading, или, если вы действительно хотите «правильный» параллелизм, используйте модуль multiprocessing, который будет запускать ваш код в отдельных процессах ОС и «обходить GIL», чего бы это ни стоило.Если вы хотите что-то конкретно асинхронное, есть новый модуль futures, который обеспечивает такие вещи.Если вам действительно нужно , чтобы поспать какое-то время, просто позвоните time.sleep.

В любом случае, придерживайтесь чего-то высокого уровня и, следовательно, менее подверженного ошибкам, чем пытаясь сделать это самостоятельновремя и расписание для конкретного приложения, это не простая проблема для решения!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...