如何为两个不同的队列创建线程以并行运行? - 蟒蛇



我有两个用于不同任务的队列,第一次爬网将开始抓取列表中的链接,然后它将生成更多链接以爬网到队列一,还将生成指向队列二上不同任务的新链接,我的程序正在工作,但问题是: 当队列 2 的工作线程开始运行时,它会停止队列 1 的工作线程, 他们基本上不是并行运行的,而是在等待对方完成任务。如何使它们并行运行?

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()

这是因为您的处理似乎在工作和工作二之间并不并行。

这是发生的情况:

  1. 您为工作和work_two创建工作人员
  2. 爬网称为
  3. Create_jobs被称为 - "工作"工人开始处理它们
  4. Create_jobsqueue.join()等待,直到他们都完成
  5. Crawl_two被称为
  6. Create_jobs_two被称为 - "work_two"工人开始处理它们
  7. Create_jobs_twoqueue_two.join()等待,直到他们都完成
  8. 调用爬网(再次从 2 开始(

基本上,您永远不会进入工作和work_two并行运行的情况,因为您使用 queue.join(( 等待所有当前正在运行的任务完成。只有这样,您才会将任务分配给"其他"队列。 您的工作和work_two本身确实并行运行,但控制结构确保工作和work_two是相互排斥的。如果您希望循环和队列并行运行,则需要重新设计它们。

您可能还需要研究如何使用threading.Lock()来保护全局new_links变量,因为我假设您将在工作线程中向其追加内容。这绝对没问题,但您需要一个锁来确保两个线程不会同时尝试执行此操作。但这与您当前的问题无关。这只会帮助您避免下一个问题。

我当然不知道你在这里试图实现什么,但你可以尝试解决你的问题,并通过完全取消全球new_links来避免下一个问题。如果你的工作和work_two只是在需要向他们提交任务时馈送其他工作人员的队列,而不是将项目放入全局变量中,然后将它们馈送到主线程中的队列,该怎么办?

或者,您可以构建一个"业务流程"线程,该线程将任务排队给工作线程,处理来自它们的响应,然后相应地对该响应进行操作,将其排队回其中一个队列,或者在结果"就绪"时接受结果。

相关内容

  • 没有找到相关文章

最新更新