python线程、协程
线程
创建线程对象
from threading import Threadt = Thread()
# 功能:创建线程对象
# 参数:target 绑定线程函数
# args 元组 给线程函数位置传参
# kwargs 字典 给线程函数键值传参
启动线程
t.start() # 启动线程
回收线程
t.join([timeout]) # 回收线程
示例
import threading
from time import sleep,ctimeloops=[4,2]def loop(nloop,nsec):print('start loop',nloop ,' at:',ctime())sleep(nsec)print('loop',nloop ,'done at:',ctime())def main():threads=[]nloops = range(len(loops))for i in nloops:# 注意传参t = threading.Thread(target=loop,args=(i,loops[i]))threads.append(t)for in in nloops:threads[i].start()for i in nloops:threads[i].join()if __name__ == '__main__':main()
自定义线程类
import threading
from time import sleep,ctimeloops=[4,2]class MyThread(threading.Thread):def __init__(self,func,args,name=''):threading.Thread.__init__(self)self.func = funcself.args = argsself.name = namedef run(self):self.func(*self.args)def loop(nloop,nsec):print('start loop',nloop ,' at:',ctime())sleep(nsec)print('loop',nloop ,'done at:',ctime())def main():threads=[]nloops = range(len(loops))for i in nloops:t = MyThread(loop,(i,loops[i]),loop.__name__)threads.append(t)for in in nloops:threads[i].start()for i in nloops:threads[i].join()if __name__ == '__main__':main()
Event 线程同步
线程之间用于交互的一个对象,这个event是一个内部的标签,线程可以等待这个标签的状态
如果标签(event)没有设置,则线程会一直等待(此时wait是阻塞模式)
import threading
# 创建线程event对象
e = threading.Event()# 设置e, 使wait结束阻塞
e.wait([timeout]) # 阻塞等待e被set
e.set() # 使e回到未被设置状态
e.clear() # 查看当前e是否被设置
e.is_set()
import threading
import time
import random# 先定义一个灯的函数,由灯的线程去调用这个函数,绿灯是允许通过,红灯是不允许通过,其中绿灯10s,红灯也是10s,这里就要用到事件
# 如果是绿灯,则设置事件的状态,如果是红灯,则取消事件的状态,初始状态为红灯
def light(event):if event.is_set():#设置初始状态,该初始状态为事件没有状态,则进程一直会阻塞event.clear()count = 0while True:#进入交通灯灯循环的状态if count < 10:print("----red light on----")elif count < 20:print("----green light on----")if not event.is_set():event.set()else:passelse:count = 0if event.is_set():event.clear()count += 1time.sleep(1)# 在定义一个车的函数,由车的线程去调用这个函数
def car(n,event):while True:time.sleep(1)if event.is_set():print("car [%(name)s] is running" %{"name":n})else:print("car [%(name)s] is waiting for red light" % {"name": n})event.wait()if __name__ == '__main__':event = threading.Event()light_thread = threading.Thread(target=light,args=(event,))light_thread.start()for i in range(6):t = threading.Thread(target=car, args=[i,event])t.start()
线程锁 Lock
lock.acquire() 上锁 如果lock已经上锁再调用会阻塞
lock.release() 解锁
with lock: 上锁
…
…
with 代码块解锁自动解锁
from threading import Thread, Lock
a = b = 0
lock = Lock()def value():while True:# 上锁lock.acquire()print('a=%d,b=%d' % (a, b)) if a != b else print('a不等于b')# 解锁lock.release()t = Thread(target=value)
t.start()
while True:# with 开始上锁with lock:a += 1b += 1# with 解锁 自动解锁
t.join()
print('程序结束')
协程
协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。
协程的标准定义:
- 必须在只有一个单线程里实现并发
- 修改共享数据不需加锁
- 用户程序里自己保存多个控制流的上下文栈
- 一个协程遇到IO操作自动切换到其它协程
协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此,协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。线程是CPU控制的,而协程是程序自身控制的。
生成器(yield)
Python中的生成器本身就具有状态保存和恢复的功能,非常适合用来实现协程。生成器协程的最大特点在于使用yield语句来挂起函数并保存函数状态。
def simple_corouctine():print('-> corouctine started')x = yield # yeild接收my_continue.send发送的信息print('-> corouctine received:',x)# 调用协程
my_corouctine = simple_corouctine()
print(my_corouctine)
# 先启动协程,让协程处于暂停状态
next(my_corouctine) # 程序通过调用方法next()将生成器推进到第一个yield语句处
# 发送消息给协程,回复执行,打印消息
my_corouctine.send('hello world')
async/await
在Python 3.5版本以后,Python提供了原生的支持协程的语法async/await。它提供了更简洁的语法,更好的可读性。
import asyncio async def countdown(n):while n >0 :print(f'T-minux {n}')await asyncio.sleep(1)# yield from asyncio.sleep(1) # 效果同上n -=1loop = asyncio.get_event_loop()
loop.run_until_complete(countdown(5))
import asyncio async def countdown(n,msg):while n >0 :print(f'{msg} - {n}')await asyncio.sleep(1)# yield from asyncio.sleep(1) # 效果同上n -=1
task_list = [asyncio.ensure_future(countdown(5,'A')),asyncio.ensure_future(countdown(2,'B')),asyncio.ensure_future(countdown(3,'C'))
]loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(task_list))
获取返回值
import asyncioasync def firstCorouctine(): # 定义协程await asyncio.sleep(1)return '34434'# coroutine :协同程序
coroutine = firstCorouctine() # 将协程赋值给coroutine
task = asyncio.ensure_future(coroutine) # 封装为task
loop = asyncio.get_event_loop() # 获取事件循环
loop.run_until_complete(task) # 执行return_value = task.result() # 获取协程返回值
print('协程返回的值为:{}'.format(return_value))
gevent(第三方库)
gevent是一个基于协程的Python网络库,它提供了一种基于yield的编程模型,允许程序员编写异步,非阻塞代码,且易于编写和测试。
安装gevent:pip install gevent
import geventdef func1():print('func1 begin')gevent.sleep(3)print('func1 end')def func2():print('func2 begin')gevent.sleep(2)print('func2 end')def func3(no:int):print('func3 begin')gevent.sleep(2)print('func3 end')g1 = gevent.spawn(func1)
g2 = gevent.spawn(func2)
g3 = gevent.spawn(func3,3) # 传参gevent.joinall([g1, g2, g3])
monkey.path_all
在开头导入monkey.patch_all(),非常重要,会自动将 python 的一些标准模块替换成 gevent 框架,这个补丁其实存在着一些坑:
- monkey.patch_all(),网上一般叫猴子补丁。如果使用了这个补丁,gevent 直接修改标准库里面大部分的阻塞式系统调用,包括 socket、ssl、threading 和 select 等模块,而变为协作式运行。有些地方使用标准库会由于打了补丁而出现奇怪的问题(比如会影响 multiprocessing 的运行)
- 和一些第三方库不兼容(比如不能兼容 kazoo)。若要运用到项目中,必须确保其他用到的网络库明确支持Gevent。
在实际情况中协程和进程的组合非常常见,两个结合可以大幅提升性能,但直接使用猴子补丁会导致进程运行出现问题;将 thread 置成 False可以解决该问题,缺点是无法发挥 monkey.patch_all() 的全部性能。
import gevent
from gevent import monkey
monkey.patch_all(thread=False, socket=False, select=False)
pool 限制并发
协程虽然是轻量级线程,但并发数达到一定量级后,会把系统的文件句柄数占光。所以需要通过 Pool 来限制并发数。
import gevent
from gevent.pool import Pool
from gevent import monkey
monkey.patch_all()
import time,datetimedef test(tm):time.sleep(tm)print('时间:{}'.format(datetime.datetime.now()))if __name__ =='__main__':task = []# 限制最大并发pool = Pool(5)# 分配100个任务,最大并发数为5for i in range(100):task.append(pool.spawn(test,5))gevent.joinall(task)
gevent 虽然在编程方面很方便,开头使用 monkey.patch_all(),就能让你的同步代码享受到异步的性能。但坑也是存在的,所以复杂的业务场景不推荐使用 gevent,可以使用python 标准库中的 asyncio。
相关文章:
python线程、协程
线程 创建线程对象 from threading import Threadt Thread() # 功能:创建线程对象 # 参数:target 绑定线程函数 # args 元组 给线程函数位置传参 # kwargs 字典 给线程函数键值传参启动线程 t.start() # 启动线程回收线程 t.join([timeout]) # …...
AttributeError: module ‘OpenSSL.SSL’ has no attribute ‘SSLv3_METHOD
这个错误是由于在OpenSSL.SSL模块中找不到SSLv3_METHOD属性导致的。解决这个问题的方法如下: 首先,确保你已经安装了最新版本的cryptography和pyOpenSSL。你可以使用以下命令卸载并重新安装它们: 卸载cryptography:pip uninstall …...
DTCC 2023丨云原生环境下,需要什么样的 ETL 方案?
2023年8月16日~18日,第14届中国数据库技术大会(DTCC 2023)于北京隆重召开,拓数派受邀参与本次大会,PieCloudDB 技术专家邱培峰在大会做了《云原生虚拟数仓 PieCloudDB ETL 方案设计与实现》的主题演讲,详…...
在UE4虚幻引擎中加入导航网格体边界体积后丧尸不能移动和发现玩家
UE4系列文章目录 文章目录 UE4系列文章目录前言一、用到的知识点二、问题原因 前言 最近使用ue4做第一人称视角射击游戏发现问题,加入导航网格体边界体积后丧尸不能移动和发现玩家。下图是出现的问题图片 一、用到的知识点 1.行为树:控制并显示AI的决…...
华为数通方向HCIP-DataCom H12-821题库(单选题:221-240)
第201题 BGP 协议用 beer default-route-advertise 命令来给邻居发布缺省路由,那么以下关于本地 BGP 路由表变化的描述,正确的是哪一项? A、在本地 BGP 路由表中生成一条活跃的缺省路由并下发给路由表 B、在本地 BGP 路由表中生成一条不活跃的缺省路由,但不下发给…...
aarch64 arm64 部署 stable diffusion webui 笔记 【1】准备 venv 安装pytorch 验证cuda
aarch64 pytorch(没有aarch64对应版本,自行编译) pytorch-v2.0.1 cuda arm64 aarch64 torch 2.0.1cu118 源码编译笔记【2】验证cuda安装 成功_hkNaruto的博客-CSDN博客 创建venv [rootceph3 stable-diffusion-webui]# /usr/local/Python-3.10.12/bin/python3 -m v…...
从方法到目标了解什么是机器学习?
一、什么是机器学习 1、简述 机器学习是 人工智能(AI) 和计算机科学的一个分支,专注于利用数据和算法来模仿人类的学习方式,逐步提高其准确性。过去几十年来,存储和处理能力方面的技术进步催生了一些基于机器学习的创新产品,例如 Netflix 的推荐引擎和自动驾驶汽车。 机…...
Devos勒索病毒:网络安全的新威胁,勒索病毒解密,数据恢复
随着信息技术的飞速发展,网络安全问题日益凸显。近年来,一种名为Devos的勒索病毒在全球范围内肆虐,给企业和个人带来了极大的损失。本文将详细介绍Devos勒索病毒的特点、传播途径以及预防和应对措施,帮助大家更好地认识和防范这一…...
go语言的高级特性
go语言调用C语言 go tool cgo main.go...
华为VRP系统基本操作
1.实验目的 掌握一些常见的路由命令。 2.实验步骤 查看设备版本信息 display version 修改设备的名字 进入系统视图 system-view修改设备名称 sysname Datacom-Router进入接口视图 int g0/0/1进入到接口GigabitEthernet0/0/1的视图 interface GigabitEthernet 0/0/1dis…...
Milvus Cloud扩展变更:为向量数据库注入前沿增强功能
在向量数据库的不断变化中,Milvus Cloud已成为一个改变游戏规则的先锋,革新了我们存储、搜索和分析复杂向量数据的方式。通过最新版本的Milvus Cloud2.3.0,引入了一系列重要的增强和修改,为更强大、更高效的向量数据库解决方案铺平了道路。在本文中,我们将深入探讨Milvus …...
外观模式简介
概念: 外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用于访问子系统中的一组接口。外观模式隐藏了子系统的复杂性,并将其封装在一个简单易用的接口中,使得客户端可以…...
web pdf 拖拽签章
web pdf 拖拽签章 主要通过火狐的pdfjs 来实现 1. 下载js 并编译 地址 https://mozilla.github.io/pdf.js/ 按照官网当下下载并编译就得到了js 2.其实也没有什么好讲的,都是用的js中的方法,官网中都有 按照步骤就能生成一个document元素,然…...
SQLAlchemy 库创建数据库引擎和会话工厂附带SQLSERVER驱动版本确认方式
SQLAlchemy 库创建数据库引擎和会话工厂 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker# 创建数据库引擎 engine create_engine(mssqlpyodbc://user:passhost:port/database?driverODBCDriver11forSQLServer)# 创建会话工厂 Session sess…...
用Python登录账户
1 问题 如何利用python登录账户? 2 方法 账户和密码存放在文件夹中从文件夹中读取并比较密码密文验证三次后,如不成功则锁定用户 通过。。。。。。。。等证明提出的方法是有效的,能够解决开头提出的问题。 代码清单 1 import osimport getpas…...
梳理下我自已对Reactor与及IO多路复用的select\poll\epoll的理解
Reactor是一种设计思想的落地,其中IO多路复用的具体落地:select\poll\epoll。都是基于Reactor的延伸。它的核心是Reactor与资源处理器。Reactor负责监听与事件的分发,事件包括连接事件、读事件、写事件。 具体的流程是系统调用监听请求&…...
4. 广播变量
一、分区规则(DataStream Broadcast)和广播变量(Flink Broadcast) 1.1 DataStream Broadcast(分区规则) 分区规则是把元素广播给所有的分区,数据会被重复处理。 DataStream.broadcast()1.…...
GPT 内部 — I : 了解文本生成
年轻的陀思妥耶夫斯基被介绍给生成AI,通过Midjourney创建 一、说明 我经常与不同领域的同事互动,我喜欢向几乎没有数据科学背景的人传达机器学习概念的挑战。在这里,我试图用简单的术语解释 GPT 是如何连接的,只是这次是书面形式。…...
平板触控笔哪款好用?好用的第三方apple pencil
而对于那些把ipad当做学习工具的人而言,苹果Pencil就成了必备品。但因为苹果Pencil太贵了,不少的学生们买不起。因此,最佳的选择还是平替电容笔,今天在这里整理了一些高性价比的电容笔! 一、挑选电容笔的要点…...
Mac 上更新系统PATH环境变量
目录 为什么要更新系统的PATH环境变量如何更新系统的PATH环境变量1. 确保你知道工具的实际安装位置。2. 将目录(实际安装位置)添加到PATH:export PATH$PATH:/path/to/your/tools补充:通过以下方法来确定当前正在使用的是Bash还是Z…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
【java面试】微服务篇
【java面试】微服务篇 一、总体框架二、Springcloud(一)Springcloud五大组件(二)服务注册和发现1、Eureka2、Nacos (三)负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...
qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...
