Блокирующая функция - это функция, которая не возвращает, но все же оставляет ваш процесс бездействующим - не в состоянии завершить больше работы.
Вы просите нас сделать ваши функции блокировки неблокирующими. Однако - если вы не пишете операционную систему - у вас нет функций блокировки. У вас могут быть функции, которые блокируют, потому что они выполняют вызовы, блокирующие системные вызовы, или у вас могут быть функции, которые «блокируют», потому что они выполняют много вычислений.
Сделать прежний тип функции неблокируемой невозможно без того, чтобы не заблокировать базовый системный вызов. В зависимости от того, что является этим системным вызовом, может быть трудно сделать его неблокирующим без добавления цикла обработки событий в вашу программу; вам не нужно просто совершать вызов, чтобы он не блокировался, вам также нужно сделать еще один вызов, чтобы определить, что результат этого вызова будет доставлен куда-то, куда вы можете его связать.
Ответ на этот вопрос - очень длинная программа на Python и множество объяснений различных интерфейсов ОС и того, как они работают, но, к счастью, я уже написал этот ответ на другом сайте; Я назвал это Twisted . Если ваша конкретная задача уже поддерживается с помощью витого реактора , то вам повезло. В противном случае, если ваша задача соответствует какой-либо существующей концепции операционной системы, вы можете расширить реактор для ее поддержки. Практически говоря, есть только 2 из этих механизмов: файловые дескрипторы в каждой разумной операционной системе и порты завершения ввода / вывода в Windows.
В другом случае, если ваши функции потребляют много ресурсов ЦП и, следовательно, не возвращаются, они на самом деле не блокируются; ваш процесс все еще затягивается и завершает работу. Есть три способа справиться с этим:
- отдельные темы
- отдельные процессы
- если у вас есть цикл событий, напишите задачу, которая периодически дает результат, записав задачу таким образом, чтобы она выполняла некоторую работу, а затем попросите цикл событий возобновить ее в ближайшем будущем, чтобы другие задачи бежать.
В Twisted эту последнюю технику можно выполнить различными способами, но вот синтаксически удобный трюк, который облегчает ее:
from twisted.internet import reactor
from twisted.internet.task import deferLater
from twisted.internet.defer import inlineCallbacks, returnValue
@inlineCallbacks
def slowButSteady():
result = SomeResult()
for something in somethingElse:
result.workHardForAMoment(something)
yield deferLater(reactor, 0, lambda : None)
returnValue(result)