线程与信息传递 - 如何实现
为了避免混淆,我对问题进行了编辑:
这是一个名为 one.py 的文件:
import threading
count = 5
dev = threading.Thread(name='dev', target=dev,args=(workQueue,count,))
dev.setDaemon(True)
dev.start()
workQueue = Queue.Queue(10)
queueLock.acquire()
workQueue.put(word)
queueLock.release()
count = 3
time.sleep(2)
count = 5
我在这里感到困惑的是,我可以在多个线程之间放入和取出队列中的值,但在计数方面却没有反映出来。
这是为什么呢?
我到底遗漏了什么呢?
class dev ( threading.Thread ):
def test(self):
while 1:
print count
print self.EPP_Obj
queueLock.acquire()
if not self.workQueue.empty():
data = self.workQueue.get()
print data
queueLock.release()
else:
queueLock.release()
def __init__(self, workQueue, EPP_Obj):
threading.Thread.__init__(self)
self.workQueue = workQueue
self.EPP_Obj = EPP_Obj
2 个回答
4
我希望这能帮到你。我觉得你可能不知道该用哪种方法。
在Python中,有几种实现多线程的方法。
我介绍一种使用类的方法。
你运行下面的代码,就会明白了。
main.py
import stringRepeater
import Queue
workqueue = Queue.Queue()
workqueue.put('test1')
workqueue.put('test2')
workqueue.put('test3')
th = stringRepeater.stringRepeater(workqueue,5)
th.start()
print '----daemon is on ----'
th.setCount(3)
workqueue.put('test4')
workqueue.put('test5')
stringRepeater.py
import threading
class stringRepeater(threading.Thread):
def __init__(self, workQueue, count):
threading.Thread.__init__(self)
self.workQueue = workQueue
self.repeatCount = count
def run(self):
while True:
teststring = self.workQueue.get()
for i in range(self.repeatCount):
print teststring
def setCount(self, newcount):
self.repeatCount = newcount
8
我们先来看一个例子:
这是一个 Thread
的子类:
import threading
class Dev(threading.Thread):
def __init__(self, workQueue, queueLock, count):
super(Dev, self).__init__() # super() will call Thread.__init__ for you
self.workQueue = workQueue
self.queueLock= queueLock
self.count = count
def run(self): # put inside run your loop
data = ''
while 1:
with self.queueLock:
if not self.workQueue.empty():
data = self.workQueue.get()
print data
print self.count
if data == 'quit':
break
使用 with
语句是一种很聪明的方式来获取和释放锁,具体可以看看这个文档。
现在来看运行的代码:
import Queue
import time
work_q = Queue.Queue() # first create your "work object"
q_lock = threading.Lock()
count = 1
dev = Dev(work_q, q_lock, count) # after instantiate like this your Thread
dev.setDaemon(True)
dev.start()
time.sleep(1)
with q_lock:
work_q.put('word')
# word
# 1
time.sleep(1)
count = 10
with q_lock:
work_q.put('dog')
# dog
# 1
count = 'foo'
with q_lock:
work_q.put('quit')
# quit
# 1
dev.join() # This will prevent the main to exit
# while the dev thread is still running
通过上面的代码,我们可以清楚地看到 self.count
的值无论我们对 count
做什么都不会改变。
造成这种情况的原因是调用:
dev = Dev(work_q, q_lock, count)
或者
dev = Dev(work_q, q_lock, 1)
是一样的。
Arnold Moon 给你展示了一种改变 self.count
的方法。我们把这个调整到我们的例子中:
class Dev(threading.Thread):
def __init__(self, workQueue, queueLock, count):
super(Dev, self).__init__()
self.workQueue = workQueue
self.queueLock= queueLock
self.count = count
def set_count(self, value):
self.count = value
def run(self):
data = ''
while 1:
with self.queueLock:
if not self.workQueue.empty():
data = self.workQueue.get()
print data
print self.count
if data == 'quit':
break
在我们的运行代码中调用 set_count
会改变 self.count
的值:
time.sleep(1)
with q_lock:
work_q.put('word')
# word
# 1
time.sleep(1)
count = dev.count + 9
dev.set_count(count)
with q_lock:
work_q.put('dog')
# dog
# 10
count = 'foo'
with q_lock:
work_q.put('quit')
# quit
# 10
dev.join()
希望这能帮助你澄清一些疑问。