我正在使用python 3.4.2
问题是proc_q1
似乎被称为正确添加id t2_q,但是在exit_flag
设置为True
之前t2线程没有从队列中获取任务。为什么proc_q2
没有被调用?
这是一些模拟代码
import urllib.request
import threading
from queue import Queue
from xml.etree import ElementTree as ET
from urllib.parse import urlparse
class Scanner(object):
@staticmethod
def proc_q1(thread_id, q1, q2):
while not exit_flag:
t1_lck.acquire()
if not q1.empty():
new_id = q1.get()
t1_lck.release()
# add id to t2_queue for threads2 to pick up
t2_lck.acquire()
t2_q.put(new_id)
t2_lck.release()
print('proc_q1 - new_id: {}'.format(new_id))
else:
t1_lck.release()
@staticmethod
def proc_q2(thread_id, q):
t2_lck.acquire()
if not q.empty():
new_id = q.get()
t2_lck.release()
print('proc_q2 - new_id: {}'.format(new_id))
else:
t2_lck.release()
class MyT1(threading.Thread):
def __init__(self, thread_id, q1, q2):
threading.Thread.__init__(self)
self.thread_id = thread_id
self.q1 = q1
self.q2 = q2
def run(self):
print('Starting t1-thread {}'.format(self.thread_id))
Scanner.proc_q1(thread_id=self.thread_id, q1=self.q1, q2=self.q2)
print('Exiting t1-thread {}'.format(self.thread_id))
class MyT2(threading.Thread):
def __init__(self, thread_id, q):
threading.Thread.__init__(self)
self.thread_id = thread_id
self.q = q
def run(self):
print('Starting t2-thread {}'.format(self.thread_id))
Scanner.proc_q2(thread_id=self.thread_id, q=self.q)
print('Exiting t2-thread {}'.format(self.thread_id))
# Create new threads
thread_pool_size = 5
t1_list = list()
t2_list = list()
t1_q = Queue(2 * thread_pool_size)
t2_q = Queue(2 * thread_pool_size)
t1_lck = threading.Lock()
t2_lck = threading.Lock()
exit_flag = False
for i in range(thread_pool_size):
t1 = MyT1(thread_id=i, q1=t1_q, q2 = t2_q)
t1.start()
t1_list.append(t1)
t2 = MyT2(thread_id=i, q=t2_q)
t2.start()
t2_list.append(t2)
# put data on the queue
t1_lck.acquire()
for i in range(10):
t1_q.put(i)
t1_lck.release()
# Wait for empty queue
while not (t1_q.empty() and t2_q.empty()):
pass
exit_flag = True
# wait for threads2 to finish
for t in t2_list:
t.join()
# wait for threads1 to finish
for t in t1_list:
t.join()
print("Done")
这是输出(脚本无法正确退出)
Starting t1-thread 0
Starting t2-thread 0
Exiting t2-thread 0
Starting t1-thread 1
Starting t2-thread 1
Exiting t2-thread 1
Starting t1-thread 2
Starting t2-thread 2
Starting t1-thread 3
Exiting t2-thread 2
Starting t2-thread 3
Starting t1-thread 4
Exiting t2-thread 3
Starting t2-thread 4
Exiting t2-thread 4
proc_q1 - new_id: 0
proc_q1 - new_id: 1
proc_q1 - new_id: 2
proc_q1 - new_id: 3
proc_q1 - new_id: 5
proc_q1 - new_id: 4
proc_q1 - new_id: 6
proc_q1 - new_id: 7
proc_q1 - new_id: 8
proc_q1 - new_id: 9
答案 0 :(得分:0)
我认为日志输出给出了答案。
MyT2线程在队列q2填满之前退出。
退出条件是:
@staticmethod
def proc_q2(thread_id, q):
...
if not q.empty():
...
最初队列q2为空,因此队列中的所有MyT2退出都有数据。
因此,程序在while循环中永远循环:
...
while not (t1_q.empty() and t2_q.empty()):
...
顺便说一句: 锁定:据我所知,Queue的get()和put()方法是同步的。无需获取用于入队和出队的锁。
来自文档https://docs.python.org/3.4/library/queue.html:
17.7. queue — A synchronized queue class