Неблокирующий процесс или поток python
У меня есть простое приложение, которое прослушивает соединение сокета. Всякий раз, когда определенные фрагменты данных поступают в обработчик обратного вызова, вызываются с этими данными. В этом обратном вызове я хочу отправить свои данные в другой процесс или поток, поскольку это может занять много времени. Сначала я запускал код в функции обратного вызова, но он блокирует!
Каков правильный способ отменить новую задачу?
Ответы
Ответ 1
threading - это библиотека потоков, обычно используемая для многопоточности на основе ресурсов. Библиотека multiprocessing - это еще одна библиотека, но больше предназначена для выполнения интенсивных задач параллельных вычислений; Threading обычно является рекомендуемой библиотекой в вашем случае.
Пример
import threading, time
def my_threaded_func(arg, arg2):
print "Running thread! Args:", (arg, arg2)
time.sleep(10)
print "Done!"
thread = threading.Thread(target=my_threaded_func, args=("I'ma", "thread"))
thread.start()
print "Spun off thread"
Ответ 2
В модуле многопроцессорности есть пулы работников. Если вам не нужен пул работников, вы можете использовать Process, чтобы запустить что-то параллельно с вашей основной программой.
Ответ 3
import threading
from time import sleep
import sys
# assume function defs ...
class myThread (threading.Thread):
def __init__(self, threadID):
threading.Thread.__init__(self)
self.threadID = threadID
def run(self):
if self.threadID == "run_exe":
run_exe()
def main():
itemList = getItems()
for item in itemList:
thread = myThread("run_exe")
thread.start()
sleep(.1)
listenToSocket(item)
while (thread.isAlive()):
pass # a way to wait for thread to finish before looping
main()
sys.exit(0)
Сон между thread.start() и listenToSocket (item) гарантирует, что поток будет установлен до начала прослушивания. Я реализовал этот код в структуре unit test, когда мне приходилось запускать несколько процессов без черновой обработки (len (itemList)), потому что моя другая структура тестирования (listenToSocket (item)) зависела от процессов.
un_exe() может инициировать вызов подпроцесса, который может блокироваться (т.е. вызывать pipe.communicate()), чтобы выходные данные от выполнения все равно были распечатаны вовремя с выходом python script. Но природа нарезки делает это нормально.
Таким образом, этот код решает две проблемы: распечатывать данные подпроцесса без блокировки script выполнения И динамически создавать и запускать несколько потоков последовательно (улучшает обслуживание script, если я когда-либо добавляю больше элементов в свой список элементов позже).