在Python中使随机模块成为线程安全的

发布于 2021-01-29 18:01:24

我有一个应用程序,要求给定相同的随机种子,结果相同。但是我发现random.randint不是线程安全的。我已经尝试过互斥锁,但这不起作用。这是我的实验代码(很长但很简单):

import threading
import random

def child(n, a):
    g_mutex = threading.Lock()
    g_mutex.acquire()
    random.seed(n)
    for i in xrange(100):
        a.append(random.randint(0, 1000))
    g_mutex.release()

def main():
    a = []
    b = []
    c1 = threading.Thread(target = child, args = (10, a))
    c2 = threading.Thread(target = child, args = (20, b))
    c1.start()
    c2.start()
    c1.join()
    c2.join()

    c = []
    d = []
    c1 = threading.Thread(target = child, args = (10, c))
    c2 = threading.Thread(target = child, args = (20, d))
    c1.start()
    c1.join()
    c2.start()
    c2.join()

    print a == c, b == d

if __name__ == "__main__":
    main()

我想编码打印 true,true ,但是它有机会给出 false,false 。如何制作线程安全的randint?

关注者
0
被浏览
51
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    其他人指出了random以线程安全方式使用的正确方法。但是我觉得必须指出,您编写的代码对任何内容都不是线程安全的。

    def child(n, a):
        g_mutex = threading.Lock()
        g_mutex.acquire()
        random.seed(n)
        for i in xrange(100):
            a.append(random.randint(0, 1000))
        g_mutex.release()
    

    每个线程都独立运行此方法。这意味着每个线程都在创建自己的锁实例,获取它,进行工作,然后释放它。除非每个线程都试图获取相同的锁,否则没有什么可以确保非并行执行的。您需要将单个值分配给g_mutexrun方法的上下文之外。

    编辑

    我只是想补充一点,不能保证仅切换到全局锁就可以完全按照您说的做。该锁将确保一次只有一个线程在生成数字,但是不能保证哪个线程将首先启动。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看