gpt4 book ai didi

python - 为什么用threading会出现data race,而不会用gevent

转载 作者:行者123 更新时间:2023-11-28 16:40:41 27 4
gpt4 key购买 nike

我的测试代码如下,使用threading,count不是5,000,000,所以出现data race,但是使用gevent,count是5,000,000,没有data race。

难道gevent协程执行时会原子“count+=1”,而不是拆分成一个one CPU的指令来执行吗?

# -*- coding: utf-8 -*-
import threading

use_gevent = True
use_debug = False
cycles_count = 100*10000


if use_gevent:
from gevent import monkey
monkey.patch_thread()

count = 0


class Counter(threading.Thread):
def __init__(self, name):
self.thread_name = name
super(Counter, self).__init__(name=name)

def run(self):
global count
for i in xrange(cycles_count):
if use_debug:
print '%s:%s' % (self.thread_name, count)
count = count + 1

counters = [Counter('thread:%s' % i) for i in range(5)]
for counter in counters:
counter.start()
for counter in counters:
counter.join()

print 'count=%s' % count

最佳答案

复合赋值 (+=) 在 Python 中不是原子的,gevent 不会改变这一点。

使用 gevent 修补线程的计数始终为 5,000,000,因为 gevent 协程不是系统线程,gevent 的上下文切换不受操作系统控制,并且 gevent 不会切换,直到线程被阻塞(io 发生)。

对于普通线程,情况有所不同。复合赋值包含 3 个步骤(a.读取值,b.增加值,c.分配更改的值),线程切换可能发生在任何这些步骤之间。

检查下面的代码,我添加了一个将运行无限循环的新线程。对于普通线程,可以打印count,因为os会自动切换线程。但是对于gevent线程,不会打印count,因为Infinite线程一旦执行完,就永远不会结束,gevent不会因为没有IO发生而切换到其他线程。

# -*- coding: utf-8 -*-
import threading

use_gevent = True
use_debug = False
cycles_count = 100
if use_gevent:
from gevent import monkey
monkey.patch_thread()

count = 0

class Counter(threading.Thread):
def __init__(self, name):
self.thread_name = name
super(Counter, self).__init__(name=name)

def run(self):
global count
for i in xrange(cycles_count):
if use_debug:
print '%s:%s' % (self.thread_name, count)
if use_gevent:
print self.thread_name
count = count + 1

class Infinite(threading.Thread):
def run(self):
if use_gevent:
print 'Infinite ...'
while True:
pass


counters = [Counter('thread:%s' % i) for i in range(5)]
for counter in counters:
counter.start()
infinite = Infinite()
infinite.start()
for counter in counters:
counter.join()

print 'count=%s' % count

关于python - 为什么用threading会出现data race,而不会用gevent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19649030/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com