【问题标题】:Python thread safe asyncioPython 线程安全异步
【发布时间】:2020-11-29 23:08:00
【问题描述】:

我正在尝试使用 asyncio.run_in_executor 运行我的同步功能

我的协程共享数据和更新数据。 run in executor 启动线程。我需要让我的对象线程和异步安全吗?

import asyncio
from concurrent.futures import ThreadPoolExecutor

class shared:
  #complex object

def func(a, b):
    # blocking calls
    return a + b

async def main(loop):
  
    result = await loop.run_in_executor(None, func, "Hello,", " world!")
    UpdateSharedObject(result) 

Start main as 5 tasks using create_task

【问题讨论】:

  • func 调用使用shared 的公共实例吗?
  • 另外,这与您的问题无关,但我只是想确保您知道,由于全局解释器锁定,使用线程池不会让您并行运行纯粹的计算任务。 Python 线程几乎只对 io 绑定代码有用。
  • 是的。他们都共享相同的资源。阻塞调用本质上是 io 绑定的。
  • 您想从您的阻止功能中访问那些共享对象吗?
  • 是的.. 在异步和同步中

标签: python python-asyncio


【解决方案1】:

如果您从不同的线程访问(尤其是进行更改)相同的资源。然后我强烈推荐使用synchronization primitives。因为 Python 并非在所有情况下都提供这种线程安全。许多 Python 操作是原子的,但不是全部。实际上,单个操作码是线程安全的。

线程安全操作示例:

L.append(x)
L1.extend(L2)
x = L[i]
x = L.pop()

这些不是:

i = i+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1

更多信息在这里:https://docs.python.org/3/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe

至于asyncio,我同意cmets中的@user4815162342,建议你重新设计程序,使线程中执行的函数为pure functions,不要更改共享对象。因为使用线程同步以及协作多任务处理 (asyncio) 会使代码变得非常复杂并导致细微的错误。

【讨论】:

    猜你喜欢
    • 2018-11-16
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2010-10-27
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多