1. Python多线程介绍

Python提供了两个有关多线程的标准库,thread和threading。thread提供了低级别的,原始的线程和一个锁。threading则是一个高级模块,提供了对thread的封装。一般情况下,使用threading是比较好的做法。
使用threading实现线程,只需要从threading.Thread类继承,并重写其中的__init__()方法和run()方法。

from threading import Thread class MyThread(Thread): def __init__(self): Thread.__init__(self) def run(self): print(self.thread_id, "start")

threading提供了一个锁:lock = threading.Lock(),调用锁的acquire()和release()方法可以使线程获得和释放锁。

需要注意的是,Python有一个GIL(Global Interpreter Lock)机制,任何线程在运行之前必须获取这个全局锁才能执行,每当执行完100条字节码,全局锁才会释放,切换到其他线程执行。

所以Python中的多线程不能利用多核计算机的优势,无论有多少个核,同一时间只有一个线程能得到全局锁,只有一个线程能够运行。

那么Python中的多线程有什么作用呢?为什么不直接使用Python中的多进程标准库?这里要根据程序执行的是IO密集型任务和计算密集型任务来选择。

当执行IO密集型任务时,比如Python爬虫,大部分时间都用在了等待返回的socket数据上,CPU此时是完全闲置的,这种情况下采用多线程较好。

当执行计算密集型任务时,比如图像处理,大部分时间CPU都在计算,这种情况下使用多进程才能真正的加速,使用多线程不仅得不到并行加速的效果,反而因为频繁切换上下文拖慢了速度。

2. threading实现生产者消费者

from threading import Thread
import timequeue = []
class Producer(Thread):def __init__(self,name):Thread.__init__(self)  #调用未绑定的超类构造方法【必须显式调用父类的构造方法,否则不会执行父类构造方法,这个跟Java不一样】self.name = namedef run(self):while True:queue.append(1)print("Producer: %s create a product" % self.name)print("Producer: %s put a product into queue" % self.name)time.sleep(0)if len(queue) > 20:print ("queue is full!")time.sleep(1)
class Consumer(Thread):def __init__(self,name):Thread.__init__(self)self.name = namedef run(self):while True:try:queue.pop()print("Consumer: %s get a product" % self.name)time.sleep(2)except:print("Queue is empty!")time.sleep(2)print("Consumer: %s sleep 2 seconds" % self.name)if __name__ == '__main__':p1 = Producer("Producer-1")c1 = Consumer("Consumer-1")c2 = Consumer("consumer-2")p1.start()c1.start()c2.start()

输出如下:

Producer: Producer-1 create a product
Producer: Producer-1 put a product into queue
queue is full!
Producer: Producer-1 create a product
Producer: Producer-1 put a product into queue
queue is full!

分析:输出显示满了之后仍然显示了生产者在创建产品,表明线程run()方法中的运行次序被打乱了。这是因为没有加锁,导致消费者线程运行到一半的时候,生产者线程获得了CPU。

queue线程安全容器

Python提供了Queue这一线程安全的容器,可以方便的和多线程结合起来。 Queue包括:
FIFO先入先出队列Queue
LIFO后入先出队列LifoQueue
优先级队列PriorityQueue
这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。
queue_tmp = Queue.Queue(10)class Producer(Thread):def __init__(self,name):Thread.__init__(self)  #调用未绑定的超类构造方法【必须显式调用父类的构造方法,否则不会执行父类构造方法,这个跟Java不一样】self.name = namedef run(self):while True:queue_tmp.put(0)print("Producer: %s create a product" % self.name)print("Producer: %s put a product into queue\r\n" % self.name)class Consumer(Thread):def __init__(self,name):Thread.__init__(self)self.name = namedef run(self):while True:queue_tmp.get()print("Consumer: %s get a product" % self.name)

3. join()函数用法测试

join()函数的原型是join(timeout=None),它的作用是阻塞进程一直到线程退出或者到timeout的时间结束。

参考文章:https://www.jianshu.com/p/f09a112a71f7

转载于:https://www.cnblogs.com/honey-badger/p/8454873.html

多线程实现生产者消费者相关推荐

  1. Linux下实现多线程的生产者消费者问题

    Linux下实现多线程的生产者消费者问题 一.原理的理解 生产者-消费者问题是一个经典的线程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制.在同一个线程地址空间内执行的两个线程 ...

  2. python多线程实现生产者消费者_用Python实现多线程“生产者-消费者”模型的简单例子...

    用 Python 实现多线程"生产者 - 消费者"模型的简单例子 生产者消费者问题是一个著名的线程同步问题, 该问题描述如下: 有一个生产者在生产产品, 这些产品将提供给若干个消费 ...

  3. C++11 并发指南九(综合运用: C++11 多线程下生产者消费者模型详解)

    前面八章介绍了 C++11 并发编程的基础(抱歉哈,第五章-第八章还在草稿中),本文将综合运用 C++11 中的新的基础设施(主要是多线程.锁.条件变量)来阐述一个经典问题--生产者消费者模型,并给出 ...

  4. java多线程之生产者消费者问题

    今天研究了一下Java多线程,根据老师上课讲的和写的,自己写了一下多线程中的经典问题-----生产者消费者经典问题, package producerconsumer; public class Pr ...

  5. 多线程之生产者消费者模型

    生产者消费者模型 1.为什么要使用生产者和消费者模式 2.案例 1.为什么要使用生产者和消费者模式 在线程开发中,生产者就是生产线程的线程,消费者就是消费线程的线程.在多线程开发中,如果生产者如理数据 ...

  6. 爬虫--05:多线程与生产者消费者模型

    Crawler - 05: Multithreading- und Produzenten-Verbrauchermodell 多线程 一.多线程的基本介绍 1.介绍 2.程序中模拟多任务 二.创建多 ...

  7. Linux多线程实现生产者消费者进程(Linux+window代码)

    原文链接:我的个人链接 Linux 常用多线程函数 pthread_create():创建一个线程 pthread_exit():退出一个线程 pthread_jion():阻塞当前线程,直到另一个线 ...

  8. 多线程设计模式:生产者-消费者

    一.两个线程一个生产者一个消费者 需求情景 – 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个. 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法 ...

  9. Python多线程实现生产者消费者模式

    什么是生产者消费者模式 在软件开发的过程中,经常碰到这样的场景: 某些模块负责生产数据,这些数据由其他模块来负责处理(此处的模块可能是:函数.线程.进程等).产生数据的模块称为生产者,而处理数据的模块 ...

最新文章

  1. jmeter获取时间_time 函数
  2. java金字塔数字代码_Java基础代码实例 :在控制台中输出金字塔,这个金字塔是由左右对称的数字组成的。 | 学步园...
  3. 孙庆新:做产品,感觉从何而来
  4. syslog记录history历史记录
  5. CentOS7下Hive集群搭建
  6. boost::search相关的测试程序
  7. u-boot 源码分析讲解
  8. python如何操作oracle数据库_Python 操作 Oracle 数据库
  9. [vue] 删除数组用delete和Vue.delete有什么区别?
  10. layer 同步调用_关于Layer组件的同步以及减少GPU带宽的问题
  11. k-d tree算法原理及实现
  12. 1039. 到底买不买(20)-PAT乙级真题
  13. 检测到无效的异常处理程序例程。_异常控制流(1):异常概述和基本类型
  14. 解决cuda官网安装包下载速度慢的问题
  15. CS231n 课程笔记翻译
  16. 读取json本地js处理输出html,JavaScript 通过浏览器导出和读取本地 JSON 文件
  17. 编写一个生成器函数,能够生成斐波那契数列
  18. SAP-SD-ABAP-销售订单自动确认程序-AVAILABILITY_CHECK_S4-SD_BACKORDER_UPDATE
  19. JavaScript 如何求两个数的最小公倍数
  20. 左耳听风-Equifax信息泄露始末

热门文章

  1. C++ 之父讨厌比特币
  2. JavaScript 九种跨域方式实现原理 1
  3. 如何使用Visual Studio无需成本即可实现连续集成
  4. 不使用输入框如何实现下拉_使用INFINITE AJAX SCROLL实现下拉加载效果
  5. java转js_java对象转js对象
  6. js生成图片_网页骨架屏自动生成方案(dps)
  7. tiptop 编译运行_putty终于让我的TIPTOP脱离虚拟机在64位上运行了。
  8. div 高度等与html,html – 仅限CSS – 基于兄弟的div的高度
  9. css 入场动画_React系列十四 React过渡动画
  10. 最优阈值生长算法_手淘搜索阈值刻度表:让你更加清楚类目搜索增长的规律