我有两个队列用于不同的任务,第一次抓取将开始抓取列表中的链接,然后它将生成更多链接以爬网到队列1,并且还将生成到队列2上的不同任务的新链接,我的程序正在运行,但问题是:当队列2的工作人员开始运行时,它会从队列中停止工作人员,他们基本上没有并行运行,他们正在等待彼此完成任务。如何让它们并行运行?
import threading
from queue import Queue
queue = Queue()
queue_two = Queue()
links = ['www.example.com', 'www.example.com', 'www.example.com',
'www.example.com', 'www.example.com', 'www.example.com',
'www.example.com', 'www.example.com', 'www.example.com']
new_links = []
def create_workers():
for _ in range(4):
t = threading.Thread(target=work)
t.daemon = True
t.start()
for _ in range(2):
t = threading.Thread(target=work_two)
t.daemon = True
t.start()
def work():
while True:
work = queue.get()
#do something
queue.task_done()
def work_two():
while True:
work = queue_two.get()
#do something
queue_two.task_done()
def create_jobs():
for link in links:
queue.put(link)
queue.join()
crawl_two()
crawl()
def create_jobs_two():
for link in new_links:
queue_two.put(link)
queue_two.join()
crawl_two()
def crawl():
queued_links = links
if len(queued_links) > 0:
create_jobs()
def crawl_two():
queued_links = new_links
if len(queued_links) > 0:
create_jobs_two()
create_workers()
crawl()
答案 0 :(得分:0)
这是因为你的处理在工作和工作之间似乎并不平行。
这就是:
queue.join()
中等待,直到所有这些内容都完成queue_two.join()
中等待,直到所有这些都完成基本上你永远不会进入work和work_two并行运行的情况,因为你使用queue.join()等待所有当前正在运行的任务完成。只有这样,您才能将任务分配给“其他”队列。你的工作和work_two本身并行运行,但控制结构确保工作和work_two是互斥的。如果您希望它们两者并行运行,则需要重新设计循环和队列。
您可能还想调查使用threading.Lock()
来保护您的全局new_links
变量,因为我假设您将在工作线程中附加内容。这绝对没问题,但你需要一个锁来确保两个线程不会同时尝试这样做。但这与您当前的问题无关。这只能帮助您避免下一个问题。
我当然不知道你试图在这里实现什么,但是你可以通过完全废弃全局new_links来尝试解决你的问题并避免下一个问题。如果你的工作和工作 - 如果他们需要向他们提交任务,而不是将项目放入一个全局变量然后将它们提供给主线程中的队列,那么你的工作和work_two只是为其提供了什么呢?
或者您可以构建一个“编排”线程,该任务将任务排入工作人员,处理来自他们的响应,然后相应地对该响应进行操作,或者将其排队到其中一个队列,或者如果“准备好”则接受结果。