one*_*ach 4 python random thread-safety
给定相同的随机种子,我的应用程序需要相同的结果.但我发现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()
Run Code Online (Sandbox Code Playgroud)
我想编码打印真实,真实,但它有机会给出虚假,虚假.我怎样才能制作线程安全的randint?
Joh*_*ooy 16
您可以random.Random为每个线程创建单独的实例
>>> import random
>>> local_random = random.Random()
>>> local_random.seed(1234)
>>> local_random.randint(1,1000)
967
Run Code Online (Sandbox Code Playgroud)
该模块提供的函数实际上是random.Random类的隐藏实例的绑定方法.您可以实例化您自己的Random实例,以获取不共享状态的生成器.这对于多线程程序特别有用,为每个线程创建一个不同的Random实例,并使用jumpahead()方法使每个线程看到的生成序列可能不重叠.
文档并没有准确说明这个类是什么,但它确实显示class random.SystemRandom([seed]),并且random.Random([seed])似乎是相同的.
例:
local_random = random.Random(n)
for i in xrange(100):
a.append(local_random.randint(0, 1000))
Run Code Online (Sandbox Code Playgroud)
其他人指出了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()
Run Code Online (Sandbox Code Playgroud)
每个线程都独立运行该方法。这意味着每个线程都在创建自己的锁实例,获取它,执行工作,然后释放它。除非每个线程都尝试获取相同的锁,否则无法确保非并行执行。g_mutex您需要为 run 方法的上下文之外分配一个值。
编辑:
我只是想补充一点,简单地切换到全局锁并不能保证完全按照您所说的进行。该锁将确保一次只有一个线程生成数字,但它不保证哪个线程将首先启动。
| 归档时间: |
|
| 查看次数: |
4717 次 |
| 最近记录: |