Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.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 异步函数以同步(串行)方式运行,任务相互阻塞_Python_Python Asyncio - Fatal编程技术网

Python 异步函数以同步(串行)方式运行,任务相互阻塞

Python 异步函数以同步(串行)方式运行,任务相互阻塞,python,python-asyncio,Python,Python Asyncio,我使用asyncio没有任何加速。此代码段的运行方式仍然与同步作业相同。大多数示例都使用asyncio.sleep()来施加延迟,我的问题是,如果部分代码根据输入参数造成延迟,该怎么办 async def c(n): #this loop is supposed to impose delay for i in range(1, n * 40000): c *= i return n async def f(): tasks = [c(i) for

我使用asyncio没有任何加速。此代码段的运行方式仍然与同步作业相同。大多数示例都使用asyncio.sleep()来施加延迟,我的问题是,如果部分代码根据输入参数造成延迟,该怎么办

async def c(n):
    #this loop is supposed to impose delay
    for i in range(1, n * 40000):
        c *= i
   return n

async def f():
    tasks = [c(i) for i in [2,1,3]]
    r=[]
    completed, pending = await asyncio.wait(tasks)
    for item in completed:
        r.append(item.result())

    return r

if __name__=="__main__":
    loop = asyncio.get_event_loop()
    k=loop.run_until_complete(f())
    loop.close()

我希望得到[1,2,3],但我没有(串行运行时也没有时差)

异步IO不是为了获得加速,而是为了在异步环境中编程时避免“回调地狱”,例如(但不限于)非阻塞IO。由于问题中的代码不是异步的,因此使用asyncio没有什么好处,但是您可以转而研究
多处理

在上述情况下,函数被定义为async,但它运行整个计算而不等待任何结果。它还包含对未分配变量的引用,因此让我们从运行以下命令的版本开始:

async def long_calc(n):
    p = 1
    for i in range(1, n * 10000):
        p *= i
    print(math.log(p))
    return p
最后的
打印
会立即指示计算完成的时间。使用
asyncio.gather
“并行”启动多个这样的协程:

async def wait_calcs():
    return await asyncio.gather(*[long_calc(i) for i in [2, 1, 3]])
asyncio.gather
将让计算运行并在所有计算完成后返回,并按结果在参数列表中的显示顺序返回结果列表。但是运行
loop.run\u直到完成(wait\u calcs())
时打印的输出显示计算实际上并没有并行运行:

178065.71824964616
82099.71749644238
279264.3442843094
82099.71749644238
178065.71824964616
279264.3442843094
结果对应于
[2,1,3]
顺序。如果协同程序是并行运行的,那么最小的数量会首先出现,因为它的协同程序所要做的工作最少

我们可以通过在内部循环中引入no-op sleep来强制协同路由给其他协同路由一个运行的机会:

async def long_calc(n):
    p = 1
    for i in range(1, n * 10000):
        p *= i
        await asyncio.sleep(0)
    print(math.log(p))
    return p
现在,输出显示协同程序是并行运行的:

178065.71824964616
82099.71749644238
279264.3442843094
82099.71749644238
178065.71824964616
279264.3442843094

请注意,这个版本也需要更多的时间来运行,因为它涉及到在协程和主循环之间进行更多的切换。大约每一百个周期只睡一次就可以避免这种减速。

异步IO不是为了加速,而是为了在异步环境中编程时避免“回调地狱”,例如(但不限于)非阻塞IO。由于问题中的代码不是异步的,因此使用asyncio没有什么好处,但是您可以转而研究
多处理

在上述情况下,函数被定义为async,但它运行整个计算而不等待任何结果。它还包含对未分配变量的引用,因此让我们从运行以下命令的版本开始:

async def long_calc(n):
    p = 1
    for i in range(1, n * 10000):
        p *= i
    print(math.log(p))
    return p
最后的
打印
会立即指示计算完成的时间。使用
asyncio.gather
“并行”启动多个这样的协程:

async def wait_calcs():
    return await asyncio.gather(*[long_calc(i) for i in [2, 1, 3]])
asyncio.gather
将让计算运行并在所有计算完成后返回,并按结果在参数列表中的显示顺序返回结果列表。但是运行
loop.run\u直到完成(wait\u calcs())
时打印的输出显示计算实际上并没有并行运行:

178065.71824964616
82099.71749644238
279264.3442843094
82099.71749644238
178065.71824964616
279264.3442843094
结果对应于
[2,1,3]
顺序。如果协同程序是并行运行的,那么最小的数量会首先出现,因为它的协同程序所要做的工作最少

我们可以通过在内部循环中引入no-op sleep来强制协同路由给其他协同路由一个运行的机会:

async def long_calc(n):
    p = 1
    for i in range(1, n * 10000):
        p *= i
        await asyncio.sleep(0)
    print(math.log(p))
    return p
现在,输出显示协同程序是并行运行的:

178065.71824964616
82099.71749644238
279264.3442843094
82099.71749644238
178065.71824964616
279264.3442843094

请注意,这个版本也需要更多的时间来运行,因为它涉及到在协程和主循环之间进行更多的切换。大约每一百个周期只睡一次就可以避免减速。

您误解了
asyncio
。它只使用一个线程,因此对于CPU绑定的进程,例如没有IO的
for
循环,您将不会从使用它中获得任何好处。函数
c(n)
从不产生CPU,因为没有IO调用(或显式产生),因此其他代码调用永远没有机会运行。您误解了
asyncio
。它只使用一个线程,因此对于CPU绑定的进程,例如没有IO的
for
循环,您将不会从使用它中获得任何好处。函数
c(n)
从不产生CPU,因为没有IO调用(或显式产生),因此其他代码调用永远没有机会运行。