一个writer和多个reader的bytearray线程安全吗?

2024-04-23 12:17:03 发布

您现在位置:Python中文网/ 问答频道 /正文

如果只有一个writer向bytearray追加字节,而多个reader从中读取字节,那么一个或多个reader是否有可能读取既不在extend之前也不在extend之后的数据?你知道吗

例如,如果bytearray中的旧数据是0123,那么writer用4567扩展,新数据将是01234567。在扩展过程中,任何读卡器是否有可能(由于竞争条件)读取0123450123abcd之类的数据?你知道吗

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


Tags: 数据对象编辑data字节bytes过程条件
1条回答
网友
1楼 · 发布于 2024-04-23 12:17:03

如果您可以保证只有一个writer,那么它取决于您传递给bytearray.extend()方法或+=语句的iterable类型(如果它是原子的)。你知道吗

Python线程在字节码之间切换,调用bytearray.extend()或将+=语句应用于bytearray对象是一个字节码,提供的迭代不需要执行字节码。如果您传入的对象是用Python实现的iterable,那么所有的赌注都是无效的,因为这需要执行多个字节码解释步骤。你知道吗

例如:

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对象扩展将是原子的,因为对内置类型(如列表)的迭代是在本机代码中实现的:

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函数,每次都执行字节码。你知道吗

但是传入一个本机函数,比如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

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

一些本机代码将解锁全局解释器锁,允许其他Python线程在本机代码独立运行时执行,但这几乎从不涉及在Python类型上操作的代码。你知道吗

总而言之,当有疑问时,最好使用锁,不要担心迭代的对象是否是本地对象。你知道吗

相关问题 更多 >