非阻塞的Python进程或线程
我有一个简单的应用程序,它会监听一个网络连接。每当收到特定的数据时,就会调用一个回调函数,并把这些数据传给它。在这个回调函数里,我想把我的数据发送到另一个进程或线程去处理,因为处理这些数据可能需要很长时间。我最开始是在回调函数里直接运行代码,但这样会导致程序卡住!!
那我应该怎么正确地开启一个新任务呢?
3 个回答
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)之间加个睡眠时间,确保线程已经建立好,然后再开始监听。这个代码我是在一个单元测试框架中实现的,因为我需要启动多个不阻塞的进程(也就是len(itemList)次),因为我的另一个测试框架(listenToSocket(item))是依赖这些进程的。
un_exe()可以触发一个子进程的调用,这个调用可能会阻塞(比如说调用pipe.communicate()),这样执行的输出数据就能和Python脚本的输出保持同步。不过,线程的特性让这个问题变得可以接受。
所以这段代码解决了两个问题——在不阻塞脚本执行的情况下打印子进程的数据,以及动态地顺序创建和启动多个线程(如果我以后要往itemList里添加更多项目,这样维护脚本会更方便)。
37
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"