Python threading+queue实现生产消费模型

0X00 threading

Python的多线程库,虽然py的多线程在CPU密集型操作场景下是个垃圾,但是在IO密集型的场景下还是能显著提升效率的。关于threading的介绍可以查阅文档,这篇博客也不错:https://blog.csdn.net/Xin_101/article/details/86593151

使用方式一般有两种,一种是创建threading.Thread实例,传入要绑定该线程的函数,然后进行执行。另一种就是继承threading.Thread,编写自己的线程类,个人比较倾向于第二种,灵活性高。

方式1:

import threading


def func():
    print "func running"
    return

t = threading.Thread(target=func)
t.start()

方式2:

import threading
import time


class MyThread(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        # Do what you want


if __name__ == '__main__':
    thread_instance = MyThread()
    thread_instance.start()  # 创建线程实例后需要调用start方法启动线程

Q1:为什么在MyThread类中定义的是run方法来执行操作,线程实例却调用的start方法?

start()方法进行了一些关于类的前置判断,例如__init__方法是否正常被实现,该线程是否只被调用了一次,并对异常进行捕获,总而言之,这就是运行线程的入口。

0X01 threaing+queue实现生产者消费者

1.生产者

import time
import Queue

from test_thread import MyThread


class Worker:

    def __init__(self):
        self.task_queue = Queue.Queue()
        thread_instance = MyThread(self.task_queue)
        thread_instance.start()

    def run(self):
        while True:
            self.task_queue.put('Knock Knock!')
            time.sleep(2)


if __name__ == '__main__':
    worker = Worker()
    worker.run()

Worker的__init__方法实例化了一个消息队列queue和一个子线程,当运行Worker的run方法,就会每隔两秒往消息队列推送knock knock消息。

2.消费者

import threading
import time


class MyThread(threading.Thread):

    def __init__(self, task_queue):
        threading.Thread.__init__(self)
        self.task_queue = task_queue

    def run(self):
        while True:
            if not self.task_queue.empty():
                msg = self.task_queue.get(timeout=1)
                print msg
            else:
                time.sleep(1)

继承于基础的threading.Thread类,在__ini__方法中接收一个消息队列:self.task_queue,一旦该队列存在数据,就执行相应操作。

3.多消费者场景

如果需要多个消费者,那么实例化多个子线程即可,例如:

import time
import Queue

from test_thread import MyThread


class Worker:

    def __init__(self):
        self.task_queue = Queue.Queue()
        t1 = MyThread(self.task_queue)
        t1.start()
        t2 = MyThread(self.task_queue)
        t2.start()
        t3 = MyThread(self.task_queue)
        t3.start()

    def run(self):
        while True:
            self.task_queue.put('Knock Knock!')
            time.sleep(2)


if __name__ == '__main__':
    worker = Worker()
    worker.run()

注意:多线程操作共享数据时,注意数据安全问题,可使用加锁等方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值