Python自学第九周(2)
时间:2019-08-09
本文章向大家介绍Python自学第九周(2),主要包括Python自学第九周(2)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
子线程编程守护线程 当主线程结束,不管子线程结束没有,全部结束
1 #Author: Zachary 2 import threading,time 3 def run(n): 4 print("task",n) 5 time.sleep(2) 6 print("task done",n,threading.current_thread()) 7 start_time = time.time() 8 t_objs = [] 9 for i in range(50): 10 t= threading.Thread(target=run,args=("t-%s"%i ,)) 11 t.setDaemon(True) #把当前线程设置为守护线程 12 t.start() 13 t_objs.append(t) 14 15 print("-----------------all threads has finished") 16 print("cost:",time.time() - start_time) 17 ##将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务
GIL锁(线程锁)也称之为互斥锁
如果是在windows上运行
1 #Author: Zachary 2 import threading,time 3 def run(n): 4 global num 5 num += 1 6 7 num = 0 8 t_objs = [] 9 for i in range(50): 10 t= threading.Thread(target=run,args=("t-%s"%i ,)) 11 t.start() 12 t_objs.append(t) 13 for t in t_objs: 14 t.join() 15 print("-----------------all threads has finished") 16 print("num:",num)
如果在linux上运行
1 # -*- coding:utf-8 -*- 2 #Author: Zachary 3 4 import threading,time 5 def run(n): 6 global num 7 time.sleep(2) 8 num += 1 9 num = 0 10 t_objs = [] 11 for i in range(10000): 12 t= threading.Thread(target=run,args=("t-%s"%i ,)) 13 t.start() 14 t_objs.append(t) 15 for t in t_objs: 16 t.join() 17 print("-----------------all threads has finished") 18 print("num:",num)
在linux上运行此代码
结果会是
改进后加入了lock,无论在哪个平台怎么运行都不会出错
1 #Author: Zachary 2 import threading,time 3 def run(n): 4 lock.acquire() 5 global num 6 num += 1 7 lock.release() 8 lock = threading.Lock() 9 num = 0 10 t_objs = [] 11 for i in range(50): 12 t= threading.Thread(target=run,args=("t-%s"%i ,)) 13 t.start() 14 t_objs.append(t) 15 for t in t_objs: 16 t.join() 17 print("-----------------all threads has finished") 18 print("num:",num)
RLock(递归锁)
在一个大锁中还要再包含子锁
1 #Author: Zachary 2 import threading, time 3 4 def run1(): 5 print("grab the first part data") 6 lock.acquire() 7 global num 8 num += 1 9 lock.release() 10 return num 11 12 def run2(): 13 print("grab the second part data") 14 lock.acquire() 15 global num2 16 num2 += 1 17 lock.release() 18 return num2 19 20 def run3(): 21 lock.acquire() 22 res = run1() 23 print('--------between run1 and run2-----') 24 res2 = run2() 25 lock.release() 26 print(res, res2) 27 28 num, num2 = 0, 0 29 lock = threading.RLock() 30 for i in range(10): 31 t = threading.Thread(target=run3) 32 t.start() 33 while threading.active_count() != 1: 34 print(threading.active_count()) 35 else: 36 print('----all threads done---') 37 print(num, num2)
Semaphore(信号量)
互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。
1 #Author: Zachary 2 import threading, time 3 4 def run(n): 5 semaphore.acquire() #信号量获取 6 time.sleep(1) 7 print("run the thread: %s\n" % n) 8 semaphore.release() #信号量释放 9 10 semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行 11 for i in range(22): 12 t = threading.Thread(target=run, args=(i,)) 13 t.start() 14 while threading.active_count() != 1: 15 pass # print threading.active_count() 16 else: 17 print('----all threads done---')
Events
An event is a simple synchronization object;
the event represents an internal flag, and threads
can wait for the flag to be set, or set or clear the flag themselves.
event = threading.Event()
# a client thread can wait for the flag to be set
event.wait()
# a server thread can set or reset it
event.set()
event.clear()
If the flag is set, the wait method doesn’t do anything.
标志位设定了,代表绿灯,直接通行
If the flag is cleared, wait will block until it becomes set again.
标志位被清空,代表红灯,wait等待变绿灯
Any number of threads may wait for the same event.
通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子,即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯停,绿灯行的规则。
例子
简易的红绿灯切换
1 #Author: Zachary 2 import time,threading 3 event = threading.Event() 4 5 def lighter(): 6 count = 0 7 while True: 8 if count > 20 and count < 30: #改成红灯 9 event.clear() #把标志位清空 10 print("\033[41;1mred light is on...\033[0m") 11 elif count > 30: 12 event.set() #变绿灯 13 count = 0 14 else: 15 print("\033[42;1mgreen light is on...\033[0m") 16 time.sleep(1) 17 count += 1 18 light = threading.Thread(target=lighter,) 19 light.start()
加上小汽车
1 #Author: Zachary 2 import time,threading 3 event = threading.Event() 4 5 def lighter(): 6 count = 0 7 event.set() 8 while True: 9 if count > 5 and count < 10: #改成红灯 10 event.clear() #把标志位清空 11 print("\033[41;1mred light is on...\033[0m") 12 elif count > 10: 13 event.set() #变绿灯 14 count = 0 15 else: 16 print("\033[42;1mgreen light is on...\033[0m") 17 time.sleep(1) 18 count += 1 19 def car(name): 20 while True: 21 if event.is_set(): #代表绿灯 22 print("[%s] running..."%name) 23 time.sleep(1) 24 else: 25 print("[%s] sees red light,waiting..."%name) 26 event.wait() 27 print("\033[34;1m[%s] green is on,start going...\033[0m"%name) 28 29 light = threading.Thread(target=lighter,) 30 light.start() 31 car1 = threading.Thread(target=car,args=("Tesla",)) 32 car1.start()
queue队列
queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.
class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) #last in fisrt out
class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列
Queue.qsize()
Queue.empty() #return True if empty
Queue.full() # return True if full
Queue.put(item, block=True, timeout=None)
Queue.get(block=True, timeout=None)
Queue.task_done()
例子
1 #Author: Zachary 2 import queue 3 print("先进先出") 4 q = queue.Queue() #先进先出 5 q.put("d1") 6 q.put("d2") 7 q.put("d3") 8 print(q.qsize()) 9 print(q.get()) 10 print(q.get()) 11 print(q.get()) 12 # print(q.get()) #不会打印结果 13 # print(q.get_nowait()) 14 # print(q.get(block=False)) #结果与上面一行一致 15 q = queue.Queue(maxsize=3) 16 q.put(1) 17 q.put(2) 18 q.put(3) 19 # q.put(4) #不会进入队列 20 print("=============================\n") 21 22 print("后进先出") 23 q = queue.LifoQueue() #后进先出-栈 24 q.put(1) 25 q.put(2) 26 q.put(3) 27 print(q.get()) 28 print(q.get()) 29 print(q.get()) 30 print("=============================\n") 31 32 print("设置优先级") 33 q = queue.PriorityQueue() 34 q.put((10,"Zach")) 35 q.put((-1,"Zachary")) 36 q.put((6,"Jack")) 37 q.put((3,"Ajax")) 38 print(q.get()) 39 print(q.get()) 40 print(q.get()) 41 print(q.get())
生产者消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
1 #Author: Zachary 2 import threading,time,queue 3 q = queue.Queue() 4 def Producer(name): 5 count = 1 6 while True: 7 q.put("骨头%s"%count) 8 print("生产了骨头,",count) 9 count += 1 10 time.sleep(0.5) 11 def Consumer(name): 12 # while q.qsize() : 13 while True: 14 print("[%s] 取到叻[%s] 并且吃了它..."%(name,q.get())) 15 time.sleep(1) 16 17 p = threading.Thread(target=Producer,args=("Zach",)) 18 c = threading.Thread(target=Consumer,args=("Jack",)) 19 c2 = threading.Thread(target=Consumer,args=("Ajax",)) 20 p.start() 21 c.start() 22 c2.start()
原文地址:https://www.cnblogs.com/zachary26626/p/11329443.html
- 让你的笔记本更快一点——我的笔记本的性能测试和虚拟硬盘(把内存当成硬盘)的使用感觉
- 分页解决方案 之 数据访问函数库——另类的思路、另类的写法,造就了不一样的发展道路。
- 分页解决方案 之 QuickPager的使用方法(在UserControl里面使用分页控件的方法)
- 分页解决方案 之 QuickPager的使用方法(URL分页、自动获取数据)
- 分页解决方案 之 QuickPager的使用方法(PostBack分页、自定义获取数据)
- QuickPager asp.net 分页控件、表单控件等自定义控件下载 和介绍 【2009.09.07更新】
- 分页解决方案 之 QuickPager的使用方法(PostBack分页、自动获取数据)
- 【自然框架】之鼠标点功能现(二):表单控件的“应用”—— 代码?只写需要的!
- 基于Docker环境中源码部署容器Nginx
- 使用Ansible playbooks快速构建etcd集群
- 使用系统内置script和scriptreplay命令来记录操作记录
- 【机器学习】我在面试机器学习、大数据岗位时遇到的各种问题
- 【机器学习】机器学习编程语言之争狼烟再起,Python称霸?
- TiDB 1.1 Beta Release
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python实现汽车管理系统
- tp5框架基于ajax实现异步删除图片的方法示例
- Python3 jupyter notebook 服务器搭建过程
- PHP图像处理 imagestring添加图片水印与文字水印操作示例
- CentOS6.9下NFS服务安装配置教程
- Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
- PHP 枚举类型的管理与设计知识点总结
- Linux静态链接库使用类模板的快速排序算法
- TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
- php post换行的方法
- apache实现部署多个网站(一个ip部署多域名)的方法详解
- windows7 32、64位下python爬虫框架scrapy环境的搭建方法
- python实现简单名片管理系统
- PHP7创建COOKIE和销毁COOKIE的实例方法
- PHP实现新型冠状病毒疫情实时图的实例