python-全局变量
我发现了一个关于队列和线程的Python教程。代码如下:python-全局变量,python,python-multithreading,Python,Python Multithreading,我发现了一个关于队列和线程的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 = thr
#!/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类中,以执行一组规则,这些规则对于每个thread类都是不同的。将其视为封装
这就是我尝试过的:
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"
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"
我现在面临几个问题:
exitFlag=1
时,whilenotexitflag将永远不会为真从main.py导入您的线程类,并从main.py执行您想要的任何操作。不要执行mythread.py,然后让线程检查exitFlag并从main.py更改它。对#1的回答是不要使用全局变量。相反,在
myThread
子类中添加一个标志
至于问题#2,队列
类是为多线程编程而设计的,因此它的方法会自动为您处理所有需要的锁定细节,从而防止同时访问问题。这意味着您实际上不需要queueLock
将这两个建议合并到您的答案中会产生如下结果(未经测试):
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"
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)
这是有效的解决办法 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\u类导入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)
--或--
您好,谢谢您的解决方案。它就像一个符咒。不过,对您的代码进行了一次更正(在MyThread中,将workQueue替换为self.q)。哦,错过了一次——很高兴能提供帮助。你好,martineau,我回来了。我发现有必要添加queueLock。如果没有它,我的程序将不会退出主线程,如果我有比队列项目更多的线程。不清楚为什么你会有比队列项目更多的线程(不包括主线程)。无论如何,可以通过预先设置其属性(其默认初始值从创建线程继承),使已启动的线程对象不阻止主线程退出。在我的答案中的代码中,可以通过向
MyThread.\uuuu init\uuuu()
构造函数方法添加self.daemon=True
语句来实现。