多线程—Queue

本文探讨了为何在多线程中使用Queue而非全局变量进行通信的原因,强调了Queue在复杂项目中的重要性。介绍了Python的Queue模块,重点讲解了Queue的put、get、task_done、qsize、empty、full和join等关键方法,以及它们在多线程同步中的作用。
摘要由CSDN通过智能技术生成

在写博客之前,我有很大疑惑:

同一个进程之间的线程不需要通信啊,访问全局变量就行了,为什么还要有消息队列?

  • 全局变量实现线程间通信功能太有限了,举个例子一个生产者线程,一个消费者线程。如果生产的太快,消费者来不及消费怎么办?就有很多消息累积,这时候用队列的方式保存会更好。
  • 多线程最关键的是线程同步。如果是个小程序,访问同一个全局变量,当然可以,加个锁就好。但若是大型项目,还是采用消息队列来通信最靠谱。一旦架构变得复杂,多线程就很难控制,采用全局变量往往是不靠谱的,最终你会发现越来越杂乱,管理难度会越来越大,各种锁,多人一起开发的话,动不动就出严重BUG 。所以多线程最好是采用消息队列来通信,结构清晰,模式统一,便于管理,无论你的项目多大,业务量多杂乱,大家都在一套统一的机制下开发,这样做最靠谱。

Python的Queue模块主要方法,我们只需要记住两个,一个是put 放 ,另一个是get 获得,因为我们q = queue.Queue()创建了一个队列后,这个队列是空的,要先放东西进去才能从里面拿东西出来

Queue模块中的常用方法:

  • from queue import Queue
  • q = Queue(maxsize=100)
  • Queue.put() 放入数据 列队满的时候会等待
  • Queue.get() 取出数据 列队为空时会等待
  • Queue.task_done() put的时候计数 +1 ,get不会 -1, get需要和 task_done 一起使用才会 -1
  • Queue.qsize() 返回列队中现存数据的个数
  • Queue.empty() 如果队列为空,返回True,反之False
  • Queue.full() 如果队列满了,返回True,反之False
  • Queue.join() 列队中维持了一个计数,计数不为0时让主线程阻塞等待,列队计数为0时才会继续往后执行

进程queue

"""进程中 列队作为局部变量 需要传参"""
import multiprocessing

def write(q):
    for i in range(5):  # 列队只能存3个 这里有5个 所以会等q.get()取出数据后 在执行 q.put()存剩下的数据
        q.put(i)
        print('Put %s in    queue. 此时个数:%d' % (i, num))

def read(q):
    while not
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Python中的多线程和队列来实现多线程下载。下面是一个简单的示例代码: ```python import threading import queue import requests def download_file(url, save_path): response = requests.get(url) if response.status_code == 200: with open(save_path, 'wb') as file: file.write(response.content) print(f"Downloaded {save_path}") else: print(f"Failed to download {url}") def worker(queue, save_dir): while not queue.empty(): url, filename = queue.get() save_path = f"{save_dir}/{filename}" download_file(url, save_path) queue.task_done() def main(): url_list = [ ('http://example.com/file1.txt', 'file1.txt'), ('http://example.com/file2.txt', 'file2.txt'), ('http://example.com/file3.txt', 'file3.txt') ] save_dir = 'downloads' # 创建队列并将下载任务放入队列 download_queue = queue.Queue() for url, filename in url_list: download_queue.put((url, filename)) # 创建多个线程来处理下载任务 num_threads = 3 for _ in range(num_threads): thread = threading.Thread(target=worker, args=(download_queue, save_dir)) thread.start() # 等待所有线程完成 download_queue.join() if __name__ == '__main__': main() ``` 上述代码中,`download_file` 函数用于实际的文件下载操作。`worker` 函数作为线程的执行函数,不断从队列中获取下载任务并执行。`main` 函数创建线程、队列,并将下载任务放入队列,然后等待所有任务完成。 这个例子中,我们创建了一个包含3个线程的线程池,每个线程从队列中获取下载任务并执行。你可以根据需要调整线程数量和下载任务列表。 希望这可以帮助到你!如果有任何问题,请随时问我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值