在python中实现多线程时,我遇到了一些问题。这个问题对于我的用例来说非常具体。在同一个网站上浏览了许多帖子之后,我部署了最广泛建议/使用的方法。你知道吗
我从定义线程类开始,如下所示。你知道吗
class myThread(Thread):
def __init__(self, graphobj, q):
Thread.__init__(self)
self.graphobj = graphobj
self.q = q
def run(self):
improcess(self.graphobj, self.q)
我定义了我的函数来完成所有需要的处理。你知道吗
def improcess(graphobj, q):
while not exitFlag:
queueLock.acquire()
if not q.empty():
photo_id = q.get()
queueLock.release()
# Complete processing
else:
queueLock.release()
现在是我被困住的部分。我能够运行下面提到的代码完全是因为它没有任何问题。但是,如果我尝试将同一个函数包装成这样,它就会崩溃。你知道吗
def train_control(graphobj, photo_ids):
workQueue = Queue(len(photo_ids))
for i in range(1,5):
thread = myThread(graphobj=graphobj, q=workQueue)
thread.start()
threads.append(thread)
queueLock.acquire()
for photo_id in photo_ids:
workQueue.put(photo_id)
queueLock.release()
while not workQueue.empty():
pass
exitFlag = 1
for t in threads:
t.join()
我所说的中断是指线程完成了它们的工作,但它们并没有停止等待,即exitFlag从未设置为1。我不知道如何使这项工作。你知道吗
不幸的是,我们的系统的设计是这样的,这段代码需要被包装在一个可以被另一个模块调用的函数中,因此将其拉出并不是一个真正的选择。你知道吗
期待着专家们的意见。提前谢谢。你知道吗
编辑:初稿忘了提这个。我全局初始化exitFlag并将其值设置为0。你知道吗
下面是我创建的用于捕获此问题的最小可验证代码段:
import threading
import Queue
globvar01 = 5
globvar02 = 7
exitFlag = 0
globlist = []
threads = []
queueLock = threading.Lock()
workQueue = Queue.Queue(16)
class myThread(threading.Thread):
def __init__(self, threadID, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.q = q
def run(self):
print "Starting thread " + str(self.threadID)
myfunc(self.threadID, self.q)
print "Exiting thread " + str(self.threadID)
def myfunc(threadID, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
thoughtnum = q.get()
queueLock.release()
print "Processing thread " + str(threadID)
if (thoughtnum < globvar01):
globlist.append([1,2,3])
elif (thoughtnum < globvar02):
globlist.append([2,3,4])
else:
queueLock.release()
def controlfunc():
for i in range(1,5):
thread = myThread(i, workQueue)
thread.start()
threads.append(thread)
queueLock.acquire()
for i in range(1,11):
workQueue.put(i)
queueLock.release()
# Wait for queue to empty
while not workQueue.empty():
pass
exitFlag = 1
# Wait for all threads to complete
for t in threads:
t.join()
print "Starting main thread"
controlfunc()
print "Exiting Main Thread"
在生成任何线程之前,您需要确保将
exitFlag
设置为0(False
),否则在impprocess()
中它们将不会执行任何操作,并且队列将保持为非空。你知道吗如果将
exitFlag
作为全局变量,并且没有从上一次运行中清除,则可能会发生此问题。你知道吗从你的MCVE,唯一缺少的是:
但是,您可以通过使用队列中的sentinel值来关闭工作线程,从而消除queueLock和exitFlag,并消除自旋等待。工作线程将在
q.get()
上休眠,并且主线程不必旋转等待空队列:输出:
相关问题 更多 >
编程相关推荐