1 并发编程
1.1 概念
1.1.1 并发编程
同步执行多个任务
注:对于单核CPU,并不能实现真正意义的并发编程
1.2 进程
一个程序的运行实例
每个进程有自己的地址空间、内存、数据栈及辅助数据
1.3 线程
同一进程内,可被并行激活的控制流
共享相同的上下文(空间地址、数据结构)
特点:便于信息的共享和通信
线程执行顺序的差异可能导致不同的结果
1.4 python全局解释器(GIL)
特点:代码由虚拟机(解释器主循环)控制
主循环同时只能有一个控制线程执行
解释器特性而非python语言特性
注:对于数据密集型,可以采用C等语言处理,或采用多进程,而对于I/O密集密集型,则不需要
2 多线程
2.1 _thread模块
2.1.1 特点
没有控制进程结束机制
只有一个同步原语
注:下划线开头代表这个模块已经不推荐使用
2.1.2 语法
import _thread _thread.start_new_thread(function,args,**kwargs=none)
其中function为线程要执行的函数,args为函数的参数,参数需要以元组的格式写
2.2 .threading模块
2.2.1 构造线程
threading.thread(target=函数,agrs=参数)
注:还有一个办法是自定义thread派生类,重写其中的run方法
2.2.2 线程中的方法
.start() 启动线程
.join() 要求主线程等待
.name 线程名称
2.2.3 获取当前线程
threading.current_thread() 获取当前线程
2.2.4 同步原语:锁
锁名=Threading.Lock() 定义
锁名.require() 获得
锁名.release() 释放
注:支持上下文操作,with 锁名:
3 队列
3.1 模块
queue模块,分为Queue(先进先出),LifoQueue(后进先出),PriorityQueue(优先队列)等
3.2 Queue队列
构造实例:queue.Queue()
放入数据项:.put(item,block=True,timeout=none)
拿出数据项:.get(block=True,timeout=none)
声明当前队列任务处理完毕:.task_done()
队列所有项处理完毕前阻塞队列:.join()
4 multiprocessing模块
4.1 说明
在python中由于有全局解释器锁的存在,主程序上面只能有一个进程存在。对于I/O处理而言,会实时释放解释器锁,所以适合用python来做处理,而对于数据密集型,则可能需要使用低级语言来进行处理,如果是在python中,则用multiprocessing模块来处理,充分利用多核多CPU的能力。
4.2 引用
import multiprocessing
4.3 方法
与threading极为相似,主要方法包括:
multiprocessing.Process(target=函数,agrs=参数) 构造进程
进程名.start() 启动进程
进程名.join() 要求主进程等待
.name 获取进程名
multiprocessing.current_process() 获取当前进程
5 concurrent.futures模块
5.1 解释
这个模块相当于将多线程操作和多进程操作进行了集中统一,导入这个模块后,多线程和多进程都可以去使用。
5.2 concurrent.futures中使用多线程或多进程
import concurrent.futures with concurrent.futures.ThreadPoolExecutor(max_workers=数量) as executor: executor.submit(函数名,参数)
注意:与多进程或多线程中定义不同,这里不需要填写target和args
6 装饰器
6.1 特点
更明确的语法
更好的代码一致性
更好的代码维护
注:分为函数定义装饰器和类定义装饰器
6.2 对于给出的变量,需要根据情况来执行不同的函数,这时候可以使用if嵌套,或字典表来实施,推荐使用委托的方式
6.3 函数定义装饰器
原函数:
def greeting(name): print(name)
现在对函数输入希望做一些修改,加上hello
def pre_add(fun): def ccc(*args,**kwargs): return ‘hello ’+fun(*args,**kwargs) return ccc
在原函数前增加@pre_add字段后,则调用greeting函数时,会输出hello name的结果
6.4 类定义装饰器
原函数:
def greeting(name): print(name)
现在对函数输入希望做一些修改,加上hello
class pp(): def __init__(self,func): self.func=func def __call__(self,*agrs,**kwargs): return ‘hello ’+self.func(*args,**kwagrs)
在原函数前增加@pp字段后,则调用greeting函数时,会输出hello name的结果
注:函数装饰器和类装饰器使用中,推荐使用函数装饰器,因为函数装饰器对于装饰普通函数及类中的方法都可以用,而类装饰器对于类中方法的装饰比较麻烦。
6.5 参数化装饰器
在函数装饰器外在嵌套一个函数,用来输入参数。