Python:在“不在”期间更改大小的列表会导致 UB 吗?

尼诺

我有一个带有两个线程的假设程序。

items = [ 'A', 'B' ]


func1():
    while True:
        if 'C' not in items:
            # do something
        
func2():
    while True:
        items.clear()
        items.append('A')
        items.append('B')

main():
    start_new_thread(func1)
    start_new_thread(func2)

not in被执行时,我想的Python必须在内部遍历表来检查每个元素。如果func2在迭代过程中改变了这个列表的大小,是否会导致异常或UB?

安德鲁-哈里森

您永远不应该允许两个线程同时使用任何编程语言访问同一块内存。这会造成数据竞争条件,导致极其未定义的行为(如果您选择的编程语言无法检测到这一点并引发异常)。最安全的做法是使用对象强制一个线程的执行在另一个线程获得锁时停止,并等待再次修改数据是安全的。这是添加了锁的最小示例(并且还修改为实际工作代码)。

import threading

items = [ 'A', 'B' ]
lock = threading.Lock()

def func1():
    while True:
        lock.acquire()
        if 'C' not in items:
            print("C not in items")
        lock.release()

def func2():
    while True:
        lock.acquire()
        items.clear()
        items.append('A')
        items.append('B')
        lock.release()

def main():
    thread_a = threading.Thread(target=func1, daemon=True)
    thread_b = threading.Thread(target=func2, daemon=True)
    thread_a.start()
    thread_b.start()
    thread_a.join()
    thread_b.join()

main()

请注意,许多库可能会将其某些功能称为“线程安全”。这意味着它们已经处理了任何潜在的数据竞争条件,您不必担心设置锁。您可能还会遇到“原子”操作,这基本上只是意味着它们是线程安全的操作。不过,原子操作在 python 中并不是真正的东西。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章