使随机模块在Python中成为线程安全的 [英] Make the random module thread-safe in Python

查看:82
本文介绍了使随机模块在Python中成为线程安全的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an application requiring the same results given the same random seed. But I find random.randint not threadsafe. I have tried mutex but this does not work. Here is my experiment code (long but simple):

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?

I want to code to print true, true, but it stands a chance to give false, false. How can I make threadsafe randint?

推荐答案

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

Others have pointed out the proper way to use random in a thread safe way. But I feel it's important to point out that the code you wrote would not be thread-safe for anything.

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()

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

Each thread is running this method independently. That means that each thread is making their own lock instance, acquiring it, doing work, and then releasing it. Unless every thread is attempting to acquire the same lock, the there is nothing to ensure non-parallel execution. You need to assign a single value to g_mutex outside of the context of your run method.

修改:

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

I just want to add that simply switching to a global lock is not guaranteed to do exactly what you said. The lock will ensure that only one thread is generating numbers at a time, but it does not guarantee which thread will start first.

这篇关于使随机模块在Python中成为线程安全的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆