线程queue、线程进程池,协程
时间:2019-09-19
本文章向大家介绍线程queue、线程进程池,协程,主要包括线程queue、线程进程池,协程使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
线程queue
import queue
q = queue.Queue() #先进先出
q = queue.LifoQueue() #先进后出
t = queue.PriorityQueue() #优先级取数据,通常这个元组的第一个值是int类型
q.put('123')
q.put('qweqwe')
print(q.get())
print(q.get())
t.put('100', 'tank')
t.put('10', 'nick')
t.put('1', 'jason')
print(t.get())
print(t.get())
print(t.get())
q.task_done()
q.task_done()
q.join()
线程定时器
from threading import Thread, Timer
import time
def task():
print('线程执行了')
time.sleep(2)
print('线程结束了')
t = Timer(3, task) #过了3秒后开启了一个线程
t.start()
多线程实现socket服务端
#服务端
from threading import Thread
import socket
def talk(conn):
while True:
try:
info = conn.recv(1024)
if len(info) == 0: break
print(str(info, encoding = 'utf8'))
conn.send(info.upper())
except ConnectionResetError:
print('客户端关闭了一个连接')
break
conn.close()
def server_demo():
server = socket.socket(
socket.AF_INET, socket.SOCK_STREAM
)
server.bind(('127.0.0.1', 8001))
server.listen(4)
while True:
conn,addr = server.accept()
print(conn, addr)
t = Thread(target=talk)
t.start()
if __name__ == '__main__':
server_demo()
#客户端
from threading import Thread,currentThread
import socket
def client_demo():
client = socket.socket()
client.connect(('127.0.0.1', 8001))
while True:
msg = f'{currentThread().name}'
client.send(bytes(msg, encoding = 'utf8'))
info = client.recv(1024)
print(str(info, encoding = 'utf8'))
client.close()
if __name__ == '__main__':
for i in range(10):
t = Thread(target = client_demo)
t.start()
多线程中的Queue队列中join()与task_done()
'''
Queue.task_done():在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号。
Queue.join():实际上意味着等到队列为空,再执行别的操作
如果线程里每从队列里取一次,但没有执行task_done(),则join无法判断队列中到底有没有结束。
可以理解为,每task_done一次,就从队列里删掉一个元素,这样在最后Join的时候根据队列长度是否为0来判断队列是否结束,从而执行主线程
'''
import queue
q = queue.Queue()
q.put('123')
q.put('qwe')
q.task_done()
q.task_done()
q.join() #这样的话,程序不会被挂起,但是如果只有一个task_done(),则会被挂起
线程池和进程池
进程池和线程池:
池的功能限制进程数或线程数.
什么时候限制?
当并发的任务数量远远大于计算机所能承受的范围时,即无法 一次性开启过多的任务数量,我就应该考虑去限制进程数或线程数 ,从而保证服务器不崩。
## 线程池和进程池
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
from threading import currentThread
from multiprocessing import current_process
import time
def task(i):
print(f'{currentThread().name} 正在执行任务 {i}')
time.sleep(2)
print('\n\n\n')
return i**2 #每次线/进程执行完都会返回一个值
if __name__ == '__main__':
pool = ProcessPoolExecutor(5) #设置进程池的大小,每次只允许有5个进程同时运行
# pool = ThreadPoolExecutor(5)
fu_list = [] #列表用于保存任务对象
for i in range(15): #一共有15个任务
future = pool.submit(task, i) #把任务提交给进程执行
fu_list.append(future) #把任务对象加到列表中
pool.shutdown() #关闭线程池的入口
for fu in fu_list: #任务执行完接收返回值
print(fu.result())
#回调函数
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
from threading import currentThread
from multiprocessing import current_process
import time
def task(i):
print(f'{currentThread().name} 正在执行任务 {i}')
time.sleep(2)
return i**2
def fun(future):
print(future.result())
if __name__ == '__main__':
pool = ProcessPoolExecutor(5)
# pool = ThreadPoolExecutor(5)
for i in range(15):
future = pool.submit(task, i)
future.add_done_callback(fun)
'''
回调函数:
为当前任务绑定了一个函数,在当前
任务执行结束的时候会触发这个函数,会把future对象作为参数传给函数
,这个称为回调函数,处理完了回来就调用这个函数
'''
协程(待补充)
'''
python的线程用的是操作系统原生的线程
协程:单线程下实现并发
并发:切换加保存状态
多线程:主要由操作系统帮忙实现,遇到io操作或者执行时间过
长就会切换。
什么样的协程是有意义的:
遇到io切换的时候才有意义
具体:
协程概念本质是程序员抽象出来的,操作系统根本不知道协程的存在,一个线程遇到io,该线程内部把CPU切到别的任务上了,操作系统就发现不了,这样实现了单线程下效率最高
'''
'''
优点:
自己控制切换要比操作系统切换快的多
缺点:
对比多线程
自己检测所有io, 但凡有一个阻塞整体都跟着阻塞
对比多进程
无法利用多核优势
为什么要有协程(遇到io切换)?
自己控制切换要比操作系统切换快的多,降低了单个线程的io时间
'''
原文地址:https://www.cnblogs.com/michealjy/p/11553146.html
- 机器学习(10)之趣味案例理解朴素贝叶斯
- Spart DataSet数据集
- (八)高性能服务器架构设计总结3——以flamigo服务器代码为例
- (八)高性能服务器架构设计总结4——以flamigo服务器代码为例
- SQL员工部门表综合查询60题
- 如何对Scala中集合(Collections)进行排序
- 小白教程——安装和使用PyCharm
- 如何在 Scala 中科学地操作 collection(一)集合类型与操作
- Redis 一二事(2) - 在spring中使用jedis 连接调试单机redis以及集群redis
- 用 Python 制作微信好友个性签名词云图
- 用 Python 查看微信好友位置信息
- 用 Python 分析微信好友性别比例
- FreeMarker静态模板结合spring展示
- 源码阅读之Vector
- 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 数组属性和方法
- 简析Spark Streaming/Flink的Kafka动态感知
- 微信小程序开发实战(19):页面导航
- Kotlin:02-函数的声明
- 「MoreThanJava」Day 5:面向对象进阶—继承详解
- 要点1:指针、数组和复合字面量
- akka-typed(9) - 业务分片、整合,谈谈lagom, 需要吗?
- com-IFileDlg 进行文件的 打开或者保存
- 哆啦A梦?不好记!安利一下Prometheus这款开源的企业监控报警平台
- Kotlin:03-变量、常量、数据类型
- nginx工程师,需要上承天命,下召九幽
- 新版视频流媒体平台EasyNVR如何在前端显示当前页面所在位置?
- Kotlin:04-基本数据类型详细介绍
- Kotlin:05-控制流 if、when、for、while
- android: API24 及以上版本调用系统相机时报:FileUriExposedException 的解决
- Typora 完美结合 PicGo,写作体验更佳!