非阻塞的Python进程或线程

29

我有一个简单的应用程序监听套接字连接。每当某些数据块进来时,回调处理程序会使用那些数据调用。在该回调中,我想将我的数据发送到另一个进程或线程中,因为需要处理的时间可能很长。最初我在回调函数中运行代码,但它会阻塞!!

如何正确地启动一个新任务?


你是否使用任何框架?如果是,该框架也可以提供一种启动延迟任务的方式。 - Santa
没有框架,纯粹的Python疯狂。 - coryjacobsen
那么 threading 模块就是你的好朋友!启动自己的延迟任务机制。或者如果你懒的话,使用一个框架也可以。=) - Santa
3个回答

38

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"

6

多进程模块提供了工作池。如果您不需要工作池,可以使用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)

在调用listenToSocket(item)之前,thread.start()与sleep之间的休眠确保线程已经建立。我在一个单元测试框架中实现了这段代码,因为我需要启动多个非阻塞进程(len(itemList)次),因为我的另一个测试框架(listenToSocket(item))依赖于这些进程。

un_exe()可以触发一个子进程调用,该调用可能会阻塞(即调用pipe.communicate()),以便执行输出数据仍然可以及时地打印到python脚本输出中。但是,线程的本质使得这种情况变得可行。

因此,这段代码解决了两个问题——在不阻塞脚本执行的情况下打印子进程的数据,并且按顺序动态地创建和启动多个线程(如果以后我要向itemList添加更多项,则可以更好地维护脚本)。


我现在也意识到,您可以根据创建线程的threadID调用不同的命令。如果特定项目需要唯一的执行修改,则这可能很有用。笔误:'un_exe()'应为'run_exe()'。 - Benjamin Castor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接