python的多进程与多线程
文章目录
1、进程与多进程的概念
- 我们打开的每一个软件,游戏,执行的每一个python脚本都是启动一个进程。
- 软件(游戏,脚本)==进程
2、进程的口粮
CPU和内存。
3、多进程
4、线程:
先有进程在有线程
5、进程与线程的关系
- 进程提供线程执行程序的前置要求,线程在重组的资源配置下,去执行程序。
6、多线程
7、多线程的执行方式
8、进程的创建
进程的创建模块——multiprocessing
#coding :utf-8
import time
import os
def work_a():
for i in range(10):
print(i,'a',os.getpid())#getpid函数是返回进程号
time.sleep(1)
def work_b():
for i in range(10):
print(i,'b',os.getpid())
time.sleep(1)
if __name__=='__main__':
start=time.time()
work_a()
work_b()
print(time.time()-start)
print('parent pid is %s'%os.getpid())
输出:
0 a 5824
1 a 5824
2 a 5824
3 a 5824
4 a 5824
5 a 5824
6 a 5824
7 a 5824
8 a 5824
9 a 5824
0 b 5824
1 b 5824
2 b 5824
3 b 5824
4 b 5824
5 b 5824
6 b 5824
7 b 5824
8 b 5824
9 b 5824
20.28624653816223
parent pid is 5824
可以看到进程号是5824
接下来创建进程:
#coding :utf-8
import time
import os
import multiprocessing
def work_a():
for i in range(10):
print(i,'a',os.getpid())#getpid函数是返回进程号
time.sleep(1)
def work_b():
for i in range(10):
print(i,'b',os.getpid())
time.sleep(1)
if __name__=='__main__':
start=time.time()
a_p = multiprocessing.Process(target=work_a)#创建进程。
a_p.start()
work_b()
print(time.time()-start)
print('parent pid is %s'%os.getpid())
输出:
0 b 35832
0 a 39172
1 b 35832
1 a 39172
2 b 35832
2 a 39172
3 b 35832
3 a 39172
4 b 35832
4 a 39172
5 b 35832
5 a 39172
6 b 35832
6 a 39172
7 b 35832
7 a 39172
8 b 35832
8 a 39172
9 b 35832
9 a 39172
10.158947944641113#时间减半。
parent pid is 35832
a,b同时执行,且进程号不一样。
#coding :utf-8
import time
import os
import multiprocessing
def work_a():
for i in range(10):
print(i,'a',os.getpid())#getpid函数是返回进程号
time.sleep(1)
def work_b():
for i in range(10):
print(i,'b',os.getpid())
time.sleep(1)
if __name__=='__main__':
start=time.time()#主进程
a_p = multiprocessing.Process(target=work_a)#子进程1
#a_p.start()#子进程1执行
b_p=multiprocessing.Process(target=work_b)#子进程2
#b_p.start()#子进程2执行
for p in (a_p, b_p):
p.start()
for p in (a_p,b_p):
p.join()#直到子进程全部执行完。
print(time.time()-start)#主进程代码2
print('parent pid is %s'%os.getpid())#主进程代码3
输出:
0 a 39036
0 b 37692
1 a 390361 b 37692
2 2b 37692
a 39036
3 a 339036 b 37692
44 ab 3903637692
5 b 376925 a 39036
6 a 390366
b 37692
7 b 376927
a 39036
8 a 390368
b 37692
9 9b a 39036
37692
10.195177793502808
parent pid is 33264
9、多进程的问题
- 通过进程模块执行的函数无法获取返回值
- 多个进程同时修改文件可能会出现错误
- 进程数量太多可能会造成资源不足,甚至死机
10、进程池与进程锁。
什么是进程池:
进程池可想象为一个池子。其中的进程可以重复使用。避免创建和关闭的消耗。
进程池的创建—multiprocessing
进程锁
11、进程的通信
进程与进程之间用队列进行通信
队列的创建:
#coding:utf-8
import json
import multiprocessing
class Work(object):
def __init__(self,q):
self.q=q
def send(self,message):
if not isinstance(message,str):
message = json.dumps(message)
self.q.put(message)
def receive(self):
while 1:
result=self.q.get()
try:
res = json.loads(result)
except:
res = result
print('recv is %s'%res)
if __name__ =='__main__':
q=multiprocessing.Queue()
work=Work(q)
send = multiprocessing.Process(target=work.send,args=({'name':'xiaoming'}))
recv= multiprocessing.Process(target=work.receive)
send.start()
recv.start()
send.join()
12、线程的创建
threading模块
线程对象的方法
13、线程池
创建:
14、GIL全局锁
GIL的作用
- 单一CPU工作
- 线程安全
- pypy
- 多进程加多线程
15、初探异步
多线程与多进程的兄弟。
什么是异步:
可以将两个不同语句一起执行。
- 异步是一种轻量级的线程
- 可以获取异步函数的返回值
- 在主进程需要是异步才行
- 适合文件读写
关键字async和await
- async定义异步
- await执行异步
async def test():
return 'a'
async def handle():
result = await test()#执行异步函数test
asyncio调用async函数
async def main():
result = await asyncio.gather(
a(),
b()
)
print(result)
if __name__=='__main__':
asyncio.run(main())