Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python threading.Thread.join()正在阻塞_Python_Multithreading_Python 3.x_Python Asyncio - Fatal编程技术网

Python threading.Thread.join()正在阻塞

Python threading.Thread.join()正在阻塞,python,multithreading,python-3.x,python-asyncio,Python,Multithreading,Python 3.x,Python Asyncio,我正在使用异步编程,并根据以下线程的一些想法编写了一个用于线程安全执行协同例程的小包装器类:。经过一些调试后,我发现在调用Thread类的join()函数时它挂起(我只为测试而重写它)。我认为我犯了一个错误,我基本上复制了OP说他使用的代码,并对其进行了测试,以发现相同的问题 他略微改动的代码: import threading import asyncio from concurrent.futures import Future import functools class EventLo

我正在使用异步编程,并根据以下线程的一些想法编写了一个用于线程安全执行协同例程的小包装器类:。经过一些调试后,我发现在调用Thread类的join()函数时它挂起(我只为测试而重写它)。我认为我犯了一个错误,我基本上复制了OP说他使用的代码,并对其进行了测试,以发现相同的问题

他略微改动的代码:

import threading
import asyncio
from concurrent.futures import Future
import functools

class EventLoopOwner(threading.Thread):
    class __Properties:
        def __init__(self, loop, thread, evt_start):
            self.loop = loop
            self.thread = thread
            self.evt_start = evt_start

    def __init__(self):
        threading.Thread.__init__(self)
        self.__elo = self.__Properties(None, None, threading.Event())

    def run(self):
        self.__elo.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.__elo.loop)
        self.__elo.thread = threading.current_thread()
        self.__elo.loop.call_soon_threadsafe(self.__elo.evt_start.set)
        self.__elo.loop.run_forever()

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

    def _add_task(self, future, coro):
        task = self.__elo.loop.create_task(coro)
        future.set_result(task)

    def add_task(self, coro):
        self.__elo.evt_start.wait()
        future = Future()
        p = functools.partial(self._add_task, future, coro)
        self.__elo.loop.call_soon_threadsafe(p)
        return future.result()  # block until result is available

    def cancel(self, task):
        self.__elo.loop.call_soon_threadsafe(task.cancel)

async def foo(i):
    return 2 * i

async def main():
    elo = EventLoopOwner()
    elo.start()

    task = elo.add_task(foo(10))
    x = await task

    print(x)
    elo.stop(); print("Stopped")
    elo.join(); print("Joined")  # note: giving it a timeout does not fix it

if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    assert isinstance(loop, asyncio.AbstractEventLoop)
    try:
        loop.run_until_complete(main())
    finally:
        loop.close()
大约50%的时候,当我运行它时,它只是暂停并说“停止”,但不是“加入”。我做了一些调试,发现它与任务本身何时发送异常相关。这种情况并非每次都会发生,但由于它是在调用
threading.Thread.join()
时发生的,因此我必须假设它与循环的破坏有关。这可能是什么原因造成的

例外情况很简单:
“无法加入当前线程”
,这告诉我,
.join()
有时在调用它的线程上运行,有时在ELO线程上运行

发生了什么,我如何修复它

为此,我正在使用Python 3.5.1

注意:这不会在IDE One上复制:

协例程的线程安全执行的“(包装类)意味着什么?你想达到什么目标?协同路由已经提供了并发性,没有线程!