gpt4 book ai didi

python - `bytearray` 对于一个写入器和多个读取器来说是线程安全的吗?

转载 作者:行者123 更新时间:2023-12-01 08:11:54 25 4
gpt4 key购买 nike

如果只有一个写入器将字节附加到一个bytearray,并且多个读取器从中读取数据,那么是否有可能一个或多个读取器读取既不在扩展之前也不在扩展之后的数据?

例如,如果bytearray中的旧数据是0123,那么编写器使用4567扩展,新数据将是01234567。任何读取器都可以(由于竞争条件)在扩展期间读取诸如 0123450123abcd 之类的数据吗?

编辑。编写器将调用.extend(data)或使用+= data将数据添加到bytearraydata 是一个 bytes 或另一个 bytearray 对象。

最佳答案

如果您可以保证只有一个编写器,那么它取决于您传递给 bytearray.extend() 方法或 + 的可迭代类型 = 语句是否是原子的。

Python 线程在“字节码之间”切换,并调用 bytearray.extend() 或将 += 语句应用于 bytearray 对象是单个字节码,假设迭代不需要执行字节码。如果您传入的对象是用 Python 实现的可迭代对象,那么一切都将失败,因为这需要执行多个字节码解释步骤。

例如:

to_extend = (int(v) for v in '0123456789')
shared_bytearray_reference += to_extend # not atomic, readers can see between 0 and 10 bytes appended

不会是原子的,因为生成器表达式循环是在Python中实现的。

但是从 list 对象扩展将是原子的,因为内置类型(例如列表)的迭代是在 native 代码中实现的:

to_extend = [int(v) for v in '0123456789']
shared_bytearray_reference += to_extend # atomic, readers will see 10 bytes appended

同样,如果您将 map() 迭代器与 Python 函数一起使用:

to_extend = map(lambda v: int(v), '0123456789')`
shared_bytearray_reference += to_extend # not atomic, readers can see between 0 and 10 bytes appended

这不是原子的,因为每个迭代步骤都会调用一个 Python 函数,并且每次都会执行字节码。

但传入一个 native 函数,例如 int:

to_extend = map(int, '0123456789')  # int is a built-in native function
shared_bytearray_reference += to_extend # atomic, readers will see 10 bytes appended

然后一切都可以在单个字节码解释步骤中执行。

某些 native 代码将解锁全局解释器锁,允许其他 Python 线程在 native 代码独立运行时执行,但这几乎从不涉及对 Python 类型进行操作的代码。

总而言之,当有疑问时,最好使用锁,而不用担心您正在迭代的对象是否是 native 的。

关于python - `bytearray` 对于一个写入器和多个读取器来说是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55197439/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com