python - 全局变量
我找到了一份关于Python中队列和线程的教程。这里是代码:
#!/usr/bin/python
import Queue
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print "Starting " + self.name
process_data(self.name, self.q)
print "Exiting " + self.name
def process_data(threadName, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
data = q.get()
queueLock.release()
print "%s processing %s" % (threadName, data)
time.sleep(3)
print "%s finished processing %s" % (threadName, data)
else:
queueLock.release()
time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1
# Create new threads
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# Wait for queue to empty
while not workQueue.empty():
pass
# Notify threads it's time to exit
exitFlag = 1
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
我对Python和线程+队列非常陌生,请多多包涵。
我打算写几个线程类(比如:myThread1、myThread2等等)。在main()函数中,它会接收命令行参数,然后决定创建哪个线程类。
所以我在考虑把myThread类和main分成一个单独的Python文件。同时,我也想把process_data方法移到myThread类中,以便为每个线程类执行一套不同的规则。可以把这理解为封装。
这是我尝试过的:
mythread.py:
#!/usr/bin/python
import Queue
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print "Starting " + self.name
process_data(self.name, self.q)
print "Exiting " + self.name
def process_data(threadName, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
data = q.get()
queueLock.release()
print "%s processing %s" % (threadName, data)
time.sleep(3)
print "%s finished processing %s" % (threadName, data)
else:
queueLock.release()
time.sleep(1)
main.py
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1
# Create new threads
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# Wait for queue to empty
while not workQueue.empty():
pass
# Notify threads it's time to exit
exitFlag = 1
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
现在我遇到了一些问题:
- 我该如何把exitFlag传递给myThread类?我试着把它设置为类变量,但当我在main中设置
exitFlag=1
时,while not exitFlag
永远不会变为真。 - 我该如何把queueLock传递给这个类?情况也是一样。目前它被声明为全局变量?如果我把它设置为myThread的成员变量也不行。
3 个回答
0
这是一个可以正常工作的解决方案;
mythread_class.py
import threading
import time
class MyThread (threading.Thread):
def __init__(self, threadID, threadname, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.threadname = threadname
self.queue = q
self.__exitFlag = False
self.__signal_lock = threading.Lock()
def run(self):
print "Starting " + self.threadname
self.process_data()
print "Exiting " + self.threadname
def stop(self):
with self.__signal_lock:
self.__exitFlag = True
def process_data(self):
while not self.__exitFlag:
if not self.queue.empty():
data = self.queue.get()
print "%s processing %s" % (self.threadname, data)
time.sleep(3)
print "%s finished processing %s" % (self.threadname, data)
time.sleep(1)
main.py 从 mythread_class 导入 MyThread 导入队列 导入线程
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
workQueue = Queue.Queue(10)
threads = []
threadID = 1
# Create new threads
for tName in threadList:
thread = MyThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
for word in nameList:
workQueue.put(word)
# Wait for queue to empty
while not workQueue.empty():
pass
# Notify threads it's time to exit
for t in threads:
t.stop()
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
如果你有多个 MyThread 类,只需把这一行替换成你其他的类:
thread = MyThread(threadID, tName, workQueue)
--或者--
thread = MyThread2(threadID, tName, workQueue)
1
从main.py中导入你的线程类,然后在main.py中执行你想要的任何操作,不要去执行mythread.py。接着,让线程去检查exitFlag,并在main.py中修改它。
1
对于第一个问题的回答是,不要使用全局变量。相反,可以在你的myThread
子类中添加一个标志。
至于第二个问题,Queue
类是为了多线程编程而设计的,所以它的方法会自动处理所有需要的锁定细节,这样就能防止同时访问的问题。这意味着你其实不需要queueLock
。
把这两个建议结合起来,你的答案可能会变成这样(未经测试):
main.py
from mythread import MyThread
import Queue
import threading
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
workQueue = Queue.Queue(10)
threads = []
threadID = 1
# Create new threads
for tName in threadList:
thread = MyThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
for word in nameList:
workQueue.put(word)
# Wait for queue to empty
while not workQueue.empty():
pass
# Notify threads it's time to exit
for t in threads:
t.stop()
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
mythread.py
import threading
import time
class MyThread (threading.Thread): # note capitalization change
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
self.__exitFlag = False
self.__signal_lock = threading.Lock()
def run(self):
print "Starting " + self.name
self.process_data()
print "Exiting " + self.name
def stop(self):
with self.__signal_lock:
self.__exitFlag = True
def process_data(self):
while not self.__exitFlag:
if not self.q.empty():
data = self.q.get()
print "%s processing %s" % (self.name, data)
time.sleep(3)
print "%s finished processing %s" % (self.name, data)
time.sleep(1)