【问题标题】:Asynchronous execution with blocking while loop带有阻塞while循环的异步执行
【发布时间】:2018-07-29 15:15:31
【问题描述】:

所以这是我的方案。我有一个 python 脚本,它在一个无限循环中运行,它接受用户输入。

但是我现在希望另一个函数在阻塞的主循环(等待 python 的 input() 函数)仍在运行时每隔 n 秒执行一次操作。我研究了异步和调度,但它们似乎不适用于阻塞函数调用,还是我弄错了?

我已经研究过多处理,但还不能完全理解我应该如何做。

编辑:

if __name__ == "__main__":
    def survivor():
        count = 5
        while count:
            print("alive")
            time.sleep(8)
            count -= 1
        print("done")


    test = JobChainClient()

    cli = threading.Thread(name="cli", target=test.getShell())
    network = threading.Thread(name="network", target=survivor())

    cli.start()
    network.start()
    print("Done")

此代码获取我的 CLI,它是一个无限的 while 循环和我的网络守护程序。当我运行它时,它显然可以工作,但问题是:

(JobChain) > exit
Closing JobChain client now!
alive
alive
alive

我的循环在退出命令后中断,只有另一个线程开始,我可能只是在这里遗漏了一些东西,请纠正我。

【问题讨论】:

    标签: python asynchronous python-asyncio


    【解决方案1】:

    您不能同步阻止用户输入。每个阻塞 = 阻塞线程,它应该同时处理您的其他请求。

    为了从异步编程模式中获得最大收益,您必须在任何地方使用 async。

    主要思想是有一个没有任务阻塞的事件循环。任务应该尽快返回某种承诺,即它将在未来的某个时间以返回值实现。然后 eventloop 可以继续并立即处理您的下一个任务。

    如果你真的需要同步阻塞,你应该生成新线程来执行 cpu 密集型绑定任务。

    【讨论】:

    • 我并没有真正遇到我的任务占用大量 CPU 的问题,而是我似乎没有找到一种方法让线程 x 与我的 cli 并行运行,这是我面临的问题。我显然明白你的意思,事件循环需要非阻塞函数调用,但这更多的是我只是愚蠢,异步不是我问题的解决方案,我道歉。
    【解决方案2】:

    最简单的解决方案是在单独的线程中调用这个其他函数(每 n 秒执行一次)。

    如果您想使用 asyncio,请查看 aioconsole,它提供了 input() 的异步等效项。

    编辑
    关于更新的问题,正确的开帖方式是:

    # note the lack of parentheses after `getShell` - you only
    # want to refer to the function, not to call it (yet)
    cli = threading.Thread(name="cli", target=test.getShell)
    cli.start()
    

    【讨论】:

    • 我尝试了线程方法,但我遇到了 GIL。这是有道理的,因为我的 CLI 是阻塞的,所以在此期间无法运行另一个线程。我还研究了多处理进程,但它禁用了标准输入,所以这对我来说不是一个替代方案。但是 aioconsole 似乎是一种方法,尽管出于理解目的,我仍然想知道一种解决方法。
    • @huhnmonster GIL 不应该影响你,因为 Python 在所有阻塞调用中都会释放它。也许您应该发布另一个问题,其中包含线程方法失败的最小可重复示例。
    • 在我的问题中添加了示例。
    猜你喜欢
    • 2019-08-04
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多