Python 任务队列 & 多线程并发threading

1 篇文章 0 订阅
1 篇文章 0 订阅

Python 解释器由于设计时有GIL(Global Interpreter Lock)全局锁,导致了多线程无法利用多核。Python 实际运行是利用单核CPU。

由于存在GIL全局锁,导致python中多线程只是交替执行,在4核、8核CPU上,也仅仅能使用1核。

本文聊到的python多线程,是基于单核CPU实现线程交替执行,提高运算效率。

优点:
1、运算速度快
2、共享内存和变量,资源消耗少

threading 线程模块

threading 重点是Thread模块

import threading

目标函数可以实例化一个Thread对象,每一个Thread对象都代表一个线程,可以通过start()方法启动线程。

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

Queue队列模块

队列分为几种:FIFO\LIFO\PRIORTY

FIFO 即First in First Out,先进先出。Queue提供了一个基本的FIFO容器,使用方法很简单,maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉。如果maxsize小于或者等于0,队列大小没有限制。

LIFO 即Last in First Out,后进先出。与栈的类似,使用也很简单,maxsize用法同上

PRIORTY 构造一个优先队列。maxsize用法同上。

基本方法:
Queue.Queue(maxsize=0) FIFO, 如果maxsize小于1就表示队列长度无限
Queue.LifoQueue(maxsize=0) LIFO, 如果maxsize小于1就表示队列长度无限
Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.get([block[, timeout]]) 读队列,timeout等待时间
Queue.put(item, [block[, timeout]]) 写队列,timeout等待时间
Queue.queue.clear() 清空队列

tast_done()
意味着之前入队的一个任务已经完成。由队列的消费者线程调用。每一个get()调用得到一个任务,接下来的task_done()调用告诉队列该任务已经处理完毕。如果当前一个join()正在阻塞,它将在队列中的所有任务都处理完时恢复执行(即每一个由put()调用入队的任务都有一个对应的task_done()调用)

程序

以上介绍了多线程与队列,现在开始实现python多线程程序。

效果

执行结果

#!/usr/bin/python
# -*- coding: UTF-8 -*-


import time
import threading
from queue import Queue


class Worker(threading.Thread):
    def __init__(self, selfManager, name):
        threading.Thread.__init__(self)
        self.work_queue = selfManager.work_queue
        self.name = name
        self.start()


    def run(self):
        while True:
            try:
                if self.work_queue.empty():
                    # print("thread-%s: queue is empty, waiting for task." % self.name)
                    continue
                text = self.work_queue.get(block=True)
                # todo Anything
                print("%s thread-%s: doing task text: %s" % (str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())), self.getName(), str(text)))

                time.sleep(10)
                self.work_queue.task_done()
            except Exception as e:
                print("thread-%s: task is error: %s" % (self.getName(), str(e)))
                break


class WorkManager:
    def __init__(self, thread_num):
        self.work_queue = Queue()  # 队列对象
        self.threads = []
        self._init_thread_pool(thread_num)


    def _init_thread_pool(self, thread_num):
        """初始化线程"""
        for name in range(thread_num):
            self.threads.append(Worker(self, str(name)))


    def add_job(self, job):
        """初始化工作队列"""
        self.work_queue.put(job)


if __name__ == '__main__':
    work_manager = WorkManager(5)
    for i in range(100):
        work_manager.add_job(i)

联系方式

如果对你有帮助,可以关注作者支持一下,每天会不定时回复留言(有任何问题都可以留言哦)。

微信公众号
浮生一境
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的多线程并发可以通过使用`threading`模块来实现。`threading`模块提供了多线程编程的基本功能。 下面是一个简单的示例,展示了如何在Python中创建和启动多线程: ```python import threading def my_function(): print("This is my thread.") # 创建线程对象 my_thread = threading.Thread(target=my_function) # 启动线程 my_thread.start() # 主线程继续执行其他操作 print("This is the main thread.") ``` 在上面的示例中,我们首先定义了一个`my_function`函数,它将在新线程中执行。然后,我们使用`threading.Thread`类创建了一个线程对象`my_thread`,并将`my_function`指定为目标函数。最后,通过调用`start()`方法启动线程。 请注意,在多线程编程中,主线程和新创建的线程可以同时运行,因此在输出中可能会以不同的顺序出现不同的线程输出。 多线程并发可以用于在某些情况下提高程序的效率,特别是当涉及到I/O密集型任务时,例如网络请求或文件读写等。然而,需要注意的是,在Python中使用多线程并发时,由于全局解释器锁(GIL)的存在,多个线程无法真正并行执行CPU密集型任务。在这种情况下,可以考虑使用多进程并发来实现更好的性能。 还有其他一些用于多线程编程的高级工具和技术,例如线程同步(如锁和条件变量)、线程间通信(如队列)等,可以根据具体的需求选择合适的工具和技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值