在Python中,set.pop()是线程安全的吗?

在Python中,set.pop()是线程安全的吗?,python,Python,我知道python中的内置集类型通常不是线程安全的,但answer声称从两个相互竞争的线程调用pop()是安全的。当然,您可能会遇到异常,但您的数据没有损坏。我似乎找不到一份证明这个说法的文件。这是真的吗?请出示证件 我认为设置“pop”操作是线程安全的,因为它是原子的,从这个意义上讲,两个线程不能弹出相同的值 例如,如果另一个线程在该集合上迭代,我不会依赖它的行为 我也找不到任何具体的文档,只是一些指向这个方向的主题。Python官方文档确实会受益于此类信息 如果你看一下,你会发现它不会释放G

我知道python中的内置集类型通常不是线程安全的,但answer声称从两个相互竞争的线程调用pop()是安全的。当然,您可能会遇到异常,但您的数据没有损坏。我似乎找不到一份证明这个说法的文件。这是真的吗?请出示证件

我认为设置“pop”操作是线程安全的,因为它是原子的,从这个意义上讲,两个线程不能弹出相同的值

例如,如果另一个线程在该集合上迭代,我不会依赖它的行为

我也找不到任何具体的文档,只是一些指向这个方向的主题。Python官方文档确实会受益于此类信息

如果你看一下,你会发现它不会释放GIL

这意味着在CPython进程中一次只能发生一个
set.pop

因为,您只能通过尝试从空集弹出而导致
索引器


因此,不,您不能通过使用CPython在多个线程中从集合中弹出来破坏数据。

查看Python源代码,
set
对象只是带有一些方便方法的字典。我认为,该方法明显低于您指出的方法。阅读评论,看看是什么。你链接的同一个问题说可变类型不是线程安全的:你必须实现锁定机制,这样你就没有竞争条件。它不是线程安全的,但由于全局解释器锁,它将在CPython(例如,pypypy)中工作。但是,您不应该依赖于此,因为它是特定于实现的,在其他实现(如IronPython)中不适用。另请参见:上的Python文档以及相关的。查看我答案中的源链接。在CPython中,
set.next
set.pop
不能同时发生,因此最糟糕的情况是,如果您在
for
循环中从序列中删除一个项,而在循环中对其进行迭代,则会发生这种情况—您跳过了一个项。接受这个答案,因为它解决了我眼前的问题。来自FFFUUUTTUURREE的读者注意:请注意@Niklas(以上)的评论。