如果run()包含yield,则Python线程永远不会启动

时间:2016-12-17 23:02:13

标签: multithreading python-3.4 python-asyncio

Python 3.4,我正在尝试使用websockets模块创建一个服务器(我之前使用的是常规套接字但是想创建一个javascript客户端)当我遇到一个问题时(因为它期望异步,至少如果这些例子是值得信赖的,我以前没用过)。线程无法正常工作。如果我运行以下代码,则永远不会打印条形图,而如果我用yield from注释掉该行,则它会按预期工作。因此,收益率可能正在做一些我不太了解的事情,但为什么它甚至从未被执行过?我应该安装python 3.5吗?

import threading

class SampleThread(threading.Thread):
    def __init__(self):
        super(SampleThread, self).__init__()
        print("foo")

    def run(self):
        print("bar")
        yield from var2

thread = SampleThread()
thread.start()

1 个答案:

答案 0 :(得分:0)

这不是处理多线程的正确方法。 run既不是发电机也不是协程。应该注意,asyncio事件循环仅为主线程定义。在新线程中对asyncio.get_event_loop()的任何调用(未先使用asyncio.set_event_loop()进行设置都会引发异常。

在查看在新线程中运行事件循环之前,您应首先分析是否确实需要在自己的线程中运行事件循环。它有一个内置的线程池执行器:loop.run_in_executor()。这将从concurrent.futuresThreadPoolExecutorProcessPoolExecutor)中获取池,并提供直接从循环对象运行进程和线程的非阻塞方式。因此,这些可以是await - ed(使用Python3.5语法)

话虽这么说,如果你想从另一个线程运行你的事件循环,你可以这样做:

导入asyncio

class LoopThread(threading.Thread):
    def __init__(self):
        self.loop = asyncio.new_event_loop()

    def run():
        ayncio.set_event_loop(self.loop)
        self.loop.run_forever()

    def stop():
        self.loop.call_soon_threadsafe(self.loop.stop)

从这里开始,你仍然需要设置一种创建任务的线程安全方式等。这个线程中的一些代码是可用的,虽然我没有取得很多成功:python asyncio, how to create and cancel tasks from another thread < / p>