Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.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异步IO等待线程_Python_Asynchronous_Async Await_Python Multithreading - Fatal编程技术网

Python异步IO等待线程

Python异步IO等待线程,python,asynchronous,async-await,python-multithreading,Python,Asynchronous,Async Await,Python Multithreading,我有一种情况,我有一个“服务器”线程,它应该监听来自其他服务器线程的调用/事件,同时执行一些其他代码。最近我在Node.js上做了很多工作,所以我认为使用async/await创建一个事件循环会很好,在这里我可以等待其他线程加入事件循环,并在它们最终加入时处理它们的响应 为了测试这个想法,我用Python 3.5编写了以下测试脚本: # http://stackabuse.com/python-async-await-tutorial/ # Testing out Python's asynch

我有一种情况,我有一个“服务器”线程,它应该监听来自其他服务器线程的调用/事件,同时执行一些其他代码。最近我在Node.js上做了很多工作,所以我认为使用async/await创建一个事件循环会很好,在这里我可以等待其他线程加入事件循环,并在它们最终加入时处理它们的响应

为了测试这个想法,我用Python 3.5编写了以下测试脚本:

# http://stackabuse.com/python-async-await-tutorial/
# Testing out Python's asynchronous features
import asyncio
from time import sleep
import threading
from threading import Thread
import random

class MyThread(Thread):

    def __init__(self, message):
        Thread.__init__(self)
        self._message = message

    def run(self):
        self._return = self._message + " oli viesti"
        a = random.randint(1, 5)
        print("Sleep for ", a)
        sleep(a)
        print("Thread exiting...")


    def join(self):
        Thread.join(self)
        return self._return



async def send(message):
    t = MyThread(message)  # daemon = True
    t.start()
    print("asd")
    return t.join()

async def sendmsg(msg):
    response = await send(msg)
    print("response is ", response)


if __name__ == "__main__":
    # Initiate a new thread and pass in keyword argument dictionary as parameters
    loop = asyncio.get_event_loop()
    tasks = [
        asyncio.ensure_future(sendmsg("hippa1"), loop=loop),
        asyncio.ensure_future(sendmsg("hippa2"), loop=loop),
        asyncio.ensure_future(sendmsg("hippa3"), loop=loop)
    ]

    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
在这个例子中,我想用不同的字符串启动三个工作线程,并等待它们完成。工作人员的睡眠时间是随机的,所以当脚本运行多次时,我希望他们以随机顺序完成。事实证明,它们似乎是按顺序执行的,第二个线程在第一个线程之后开始

我的错误是什么?睡眠不应该只阻塞它所在的线程吗?我的事件循环设置是否正确?我可以异步/等待连接吗

最后,我希望将消息发送给其他线程,等待它们的响应,然后使用返回的值运行回调函数


编辑:为了澄清,最终我希望在主线程中使用async/await等待条件变量,并运行其他代码,直到一些条件变量通过执行。在这个示例代码中,我尝试对工作线程的联接执行相同的操作。

最终,由于以下代码,它按顺序运行:

async def send(message):
    t = MyThread(message)  # daemon = True
    t.start()
    print("asd")
    return t.join()
启动一个线程,然后立即等待该线程完成,然后再继续。这就是为什么它们是按顺序执行的

Node.js和asyncio不一定要创建新线程来执行它们的操作。例如,Node.js只使用单个线程,但它使用内核级函数(例如“epoll”)来调用在发生新网络活动时指示的回调。这允许单个线程管理数百个网络连接

这就是为什么当您在没有线程实例的情况下执行此操作时,可能会在当前运行的线程上调用sleep,这与主线程相同。当您将asyncio与网络功能一起使用时,您可以使用“yield from”结构,它允许在其他任务与其他远程服务一起执行时执行其他代码块

主体结构正确。您需要此代码块:

loop.run_until_complete(asyncio.wait(tasks))
但不要依赖“睡眠”来测试功能,您需要拨打网络电话,或使用:

yield from asyncio.sleep(1)

在这种情况下,不需要启动单独的线程。

时间。睡眠
不是异步的,请尝试使用
等待异步。睡眠
但它是在单独的线程中触发的,所以它不应该只阻塞单独的线程而不是事件循环所在的主线程吗?我的理解是睡眠是线程,而不是进程阻塞。那么,为什么join即使使用异步/等待结构也会阻塞我的主线程呢?关于线程启动的好观点。然而,在我的例子中,我确实需要单独的线程,但如果可能的话,我希望异步地等待来自它们的条件。所以我想有一个函数,它可以检查事件循环中的连接,但如果仍然执行其他任意代码,直到连接在循环中解锁。因此,我的案例与Node.js并不完全相似,我希望等待其他线程完成/设置条件变量,而不使用异步事件循环阻塞我的主线程。简言之,我不知道如何编写以下内容:yield t.join()。在这种情况下,我建议您根本不使用asyncio,而是使用中间的队列。您可以使用task_done()在队列中等待,并使用get()拾取工作项。然后可以使用另一个队列将结果传回主线程。文档页面上有一个代码示例显示了这一点:很高兴知道。实际上,当我无法让asyncio工作时,我最终以这种方式实现了它。建筑被证明足够干净,可以使用它。