1,进程与线程
进程优点:同时利用多个cpu 工作,能同时进行多个操作 效率高
进程缺点:浪费内存
线程优点:共享内存,io操作的时候可以并发
线程缺点:抢占资源
进程不是越多越好 最好= cpu
线程也不是越多越好 具体案例 具体分析 请求上下文切换好时
计算机中执行任务最小单位是线程
IO密集型(不用cpu):
多线程
计算密集型(用cpu):
多进程
创建线程:
import threading def f1(a): pass t = threading.Thread(target=f1,args=(1,)) t.start()
线程锁:
例如列表【0,1,2,3,4,5,6,7,8,9】,1线程从前往后读取 2线程从后往前修改 会导致任务错误,所以有了线程锁
同一时刻允许一个线程执行操作。
一般用RLock
import threading import time gl_num = 0 lock = threading.RLock() #创建Rlock对象》lock def Func(): lock.acquire() #lock.acqui加锁 global gl_num gl_num += 1 time.sleep(1) print(gl_num) lock.release() #lock.release关闭锁 for i in range(10): t = threading.Thread(target=Func) t.start()
Event事件 threading.Event 调用 有三个功能 wait 红绿灯 clear 红灯 set 绿灯
import threading
def do(event): print('start') event.wait() print('execute') event_obj = threading.Event() for i in range(10): t = threading.Thread(target=do, args=(event_obj,)) t.start() event_obj.clear() inp = input('input:') if inp == 'true': event_obj.set()
queue模块
Queue 就是队列,它是线程安全的
队列的特性:先进先出
import queue q = queue.Queue(maxsize=0) #构造一个先进先出的队列,maxsize指定队列长度,为0时,表示队列长度无限。 q.join() #等到队列为None的时候,再执行别的操作 q.qsize() #返回队列的大小(不可靠) q.empty() #当队列为空的时候,返回True 否则返回False(不可靠) q.full() #当队列满的时候,返回True,否则返回False(不可靠) q.put(item, block=True, timeout=None) #将item放入Queue尾部,item必须存在,可以参数block默认为True,表示当队列满时,会等待队列给出可用位置 #为Flase时为非阻塞,此时如果队列已经满,会引发queue.Full异常。可以选参数timeout,表示会阻塞的时间, #如果队列无法给出放入item的位置,则引发queue.Full异常。 q.get(block=True, timeout=None) #等 移除并返回队列头部的一个值,可选参数block默认为True,表示获取值的时候,如果队列为空,则阻塞,为False时,不阻塞, #若此时队列为空,则引发 queue.Empty异常。可选参数timeout,表示会阻塞设置的时候,过后,如果队列为空,则引发Empty异常。 q.put_nowait(item) #等效put(item,block=False) q.get_nowait() #不等 等效于 get(item,block=False)
创建进程:
import multiprocessing
def f1(a):
pass
if __name__ == '__main__': #win系统下创建进程需要写
p = multiprocessing.Process(target=f1,args=(1,))
p.start()
进程之间 各自持有一份数据 数据之间无法共享
但是可使用方法使进程间数据共享
m = multiprocessing.Manager()
dic = m.dict()
可实现进程间数据共享 想表现出来 需要将数据加入字典dic 中查看
import multiprocessing def f1(i,dic): dic[i] = i+100 print(dic) if __name__ == '__main__': m = multiprocessing.Manager() dic = m.dict() for i in range(10): p = multiprocessing.Process(target=f1,args=(i,dic,)) p.start() p.join()
进程池Pool
pool = Pool(5)表示设置最大五个进程同时进行的线程池
pool.apply(func=f1,args=(i,))在线程池内设置进程,apply,是排队进行,
pool.apply_async(func=f1,args=(i,))同上 只不过apply_async 是并发进行的,内部无jion,所以 需要在下面设置close,先关闭 然后jion 表示等线程关闭了 主线程再关闭 不然 线程任务没走完 主线程就不等 之间关闭了
pool.apply_async 进程daemon =True
from multiprocessing import Pool import time def f1(a): time.sleep(1) print(a) def f2(): pass if __name__ == '__main__': pool = Pool(5) for i in range(10): pool.apply(func=f1,args=(i,))
from multiprocessing import Pool import time def f1(a): time.sleep(1) print(a) def f2(): pass if __name__ == '__main__': pool = Pool(5) for i in range(50): pool.apply_async(func=f1,args=(i,)) pool.close() pool.join()
pool.apply_async()后面可选择设置回调函数 将返回值赋值给设置的回调函数
from multiprocessing import Pool import time def f1(a): time.sleep(1) return a def f2(a): print(a) if __name__ == '__main__': pool = Pool(5) for i in range(10): pool.apply_async(func=f1,args=(i,),callback=f2) pool.close() pool.join()