Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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 对于一个写入程序和多个读取程序,`bytearray`线程安全吗?_Python_Arrays_Python 3.x - Fatal编程技术网

Python 对于一个写入程序和多个读取程序,`bytearray`线程安全吗?

Python 对于一个写入程序和多个读取程序,`bytearray`线程安全吗?,python,arrays,python-3.x,Python,Arrays,Python 3.x,如果只有一个写入程序将字节追加到字节数组,并且有多个读卡器从中读取,那么一个或多个读卡器是否有可能读取扩展之前或之后都不存在的数据 例如,如果bytearray中的旧数据是0123,则写入程序扩展为4567,新数据将是01234567。任何读卡器是否可以(由于竞争条件)在扩展期间读取数据,如012345或0123abcd 编辑。编写器将调用.extend(data)或使用+=data将数据添加到字节数组中。数据是一个字节或另一个bytearray对象。如果您可以保证只有一个写入程序,那么它取决于

如果只有一个写入程序将字节追加到
字节数组
,并且有多个读卡器从中读取,那么一个或多个读卡器是否有可能读取扩展之前或之后都不存在的数据

例如,如果
bytearray
中的旧数据是
0123
,则写入程序扩展为
4567
,新数据将是
01234567
。任何读卡器是否可以(由于竞争条件)在扩展期间读取数据,如
012345
0123abcd


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

如果您可以保证只有一个写入程序,那么它取决于您传递给
bytearray.extend()
方法的iterable类型,或者
+=
语句(如果它是原子的话)

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

例如:

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

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

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类型上运行的代码


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

请显示如何追加这些字节。问题不在于附加,而在于您使用什么代码来完成它。@MartijnPieters编辑。它实际上是最简单的用例之一,使用
.extend()
+=
。好的,下面的答案适用。如果
数据
是内置序列类型或应用内置函数的
映射()
,则它是原子的,否则就不是。@MartijnPieters我的案例只涉及
字节
字节数组
。从你的回答来看,我想我现在可以保持这样。但是我想知道我们可以依赖
bytes
bytearray
上的迭代是本机的这一事实多久?这符合规格吗?对于这个用例,您会推荐一个锁还是另一个线程安全的容器?没有规范,我建议在有疑问时锁定。
to_extend = map(int, '0123456789')  # int is a built-in native function
shared_bytearray_reference += to_extend  # atomic, readers will see 10 bytes appended