我在一个类的许多实例之间共享一个计数器(training_queue)。该类继承了threading.Thread,因此它实现了run()方法。当我调用start()时,我希望每个线程都增加这个计数器,所以当它达到一个限制时,不再启动线程。但是,没有一个线程修改变量。这是代码:
class Engine(threading.Thread):
training_mutex = threading.Semaphore(MAX_TRAIN)
training_queue = 0
analysis_mutex = threading.Semaphore(MAX_ANALYSIS)
analysis_queue = 0
variable_mutex = threading.Lock()
def __init__(self, config):
threading.Thread.__init__(self)
self.config = config
self.deepnet = None
# prevents engine from doing analysis while training
self.analyze_lock = threading.Lock()
def run(self):
with self.variable_mutex:
self.training_queue += 1
print self.training_queue
with self.training_mutex:
with self.analyze_lock:
self.deepnet = self.loadLSTM3Model()
我使用Lock保护training_queue,因此它应该是线程安全的。但是,如果我总是打印它的值1.在这种情况下,线程如何影响变量范围?
答案 0 :(得分:6)
您对线程之间如何共享状态的理解是正确的。但是,您正在使用实例属性" training_queue"而不是类属性" training_queue"。
也就是说,对于每个新对象,总是将training_queue设置为1。
例如:
import threading
class Engine(threading.Thread):
training_queue = 0
print_lock = threading.Lock()
def __init__(self, config):
threading.Thread.__init__(self)
def run(self):
with Engine.print_lock:
self.training_queue += 1
print self.training_queue
Engine('a').start()
Engine('b').start()
Engine('c').start()
Engine('d').start()
Engine('e').start()
将返回:
1
1
1
1
1
可是:
import threading
class Engine(threading.Thread):
training_queue = 0
print_lock = threading.Lock()
def __init__(self, config):
threading.Thread.__init__(self)
def run(self):
with Engine.print_lock:
Engine.training_queue += 1
print self.training_queue
Engine('a').start()
Engine('b').start()
Engine('c').start()
Engine('d').start()
Engine('e').start()
返回:
1
2
3
4
5
注意self.training_queue与Engine.training_queue
顺便说一句。我认为在python中+ =应该是原子的,所以我不会打扰锁。但是,在上面的例子中没有使用lock来打印到stdout。