Python进程
1. 什么是程序?什么是进程?
进程:正在执行的程序(任务管理器里面看到的qq进程)
程序:没有执行的代码,是一个静态的(qq.exe文件)
子进程就是将父进程里面的代码复制一份
2. 使用进程实现多任务
multiprocessing模块就是跨平台的多进程模块,
提供了一个Process类来代表一个进程对象,
这个对象可以理解为是一个独立的进程,可以执行另外的事情。
3. 线程和进程之间的对比
进程:能够完成多任务,一台电脑上可以同时运行多个QQ
线程:能够完成多任务,一个QQ中的多个聊天窗口
根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
4. 进程间通信-Queue
Queue-队列 先进先出
5. 队列间简单通信
模拟下载数据,与数据处理
6. 多进程共享全局变量
共享全局变量不适用于多进程编程
7. 进程池
当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process,
动态生成多个进程,但是如果是上百甚至上千个目标,手动的去创建的进程的工作量巨大,
此时就可以用到multiprocessing模块提供的Pool方法
初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,
那么就会创建一个新的进程用来执行该请求,但是如果池中的进程数已经达到指定的最大值,
那么该请求就会等待,直到池中有进程结束,才会用之前的进程来执行新的任务
8. 进程的使用方法和线程差不多,只是将threading换成multiprocessing模块,但是他们之间也是有区别的
进程就像是一条流水线
线程就像流水线上面的每个人
生产量不够,多加一条流水线增加产量
Python队列,进程间通信(不是数据共享)
import multiprocessing,time
from multiprocessing import Queue
# put 往队列里面添加数据
# get 往队列里面提取数据
def demo1(qu):
li = [11,22,33]
for i in li:
qu.put(i)
print('put ok')
def demo2(qu):
while True:
print(qu.get())
if qu.empty():
break
print('get ok')
if __name__ == '__main__':
qu=Queue(2) #队列里面的值设置成多大,队列就又多大,不设置,按需分配
m1=multiprocessing.Process(target=demo1,args=(qu,))
m2=multiprocessing.Process(target=demo2,args=(qu,))
m1.start()
m2.start()
---------------------
11
22
put ok
get ok
Python进程池示例
import os,time,random
from multiprocessing import Pool
# coding:utf8
def work(msg):
print('{} 进程开始执行,进程id为: {}'.format(msg,os.getpid()))
time.sleep(1)
if __name__ == '__main__':
print('----start-----')
# 1个进程池由4个进程组成,其中4个进程id是永远不变的,直至程序结束
p=Pool(4)
# 10个进程想要执行,需要排队,
for i in range(0,10):
p.apply_async(work,(i,))
p.close()
p.join()
print('----end-------')
-----------------结果----------------------------
----start-----
0 进程开始执行,进程id为: 33636
1 进程开始执行,进程id为: 8220
2 进程开始执行,进程id为: 34116
3 进程开始执行,进程id为: 36820
4 进程开始执行,进程id为: 33636
5 进程开始执行,进程id为: 8220
6 进程开始执行,进程id为: 34116
7 进程开始执行,进程id为: 36820
8 进程开始执行,进程id为: 33636
9 进程开始执行,进程id为: 8220
----end-------
Python进程池间的进程通信
import os,time,random
import multiprocessing
# coding:utf8
def demo1(p):
# 进程池里面的进程出现问题,不会主动跑出异常,最好加上try方法
try:
p.put('aaaaaaa')
except Exception as e:
print(e)
exit(1)
def demo2(p):
try:
print(p.get())
except Exception as e:
print(e)
exit(1)
if __name__ == '__main__':
#进程池之间的进程通信,需要用该方法
p=multiprocessing.Manager().Queue()
po=multiprocessing.Pool(2)
po.apply_async(demo1,args=(p,))
po.apply_async(demo2,args=(p,))
po.close()
po.join()
Python进程文件夹复制(案例)
思路:
1 获取用户要copy的文件夹的名字
2 创建一个新的文件夹
3 获取文件夹的所有的待copy的文件名字
4 创建进程池
5 向进程池中添加拷贝任务
代码:
import multiprocessing
import os,time
"""
1 获取用户要copy的文件夹的名字
2 创建一个新的文件夹
3 获取文件夹的所有的待copy的文件名字
4 创建进程池
5 向进程池中添加拷贝任务
"""
def copy_file(name,new_file,old_file,q):
print('拷贝的文件名:{}'.format(name))
with open(old_file+'/'+name,'rb') as f:
res=f.read()
with open(new_file+'/'+name,'wb') as f:
f.write(res)
q.put(name)
def main():
# 1.获取用户要copy的文件夹的名字
old_file=input('请输入需要复制的文件夹名字:')
# 2.创建一个新的文件夹
new_file = old_file+'_bak'
if not os.path.exists(new_file):
os.mkdir(new_file)
# 3.获取文件夹的所有的待copy的文件名字
file_names=os.listdir(old_file)
file_count=len(file_names)
# 4.创建进程池
po=multiprocessing.Pool(2)
# 创建队列
q=multiprocessing.Manager().Queue()
for name in file_names:
po.apply_async(copy_file,(name,new_file,old_file,q))
po.close()
copy_count=0
while True:
f=q.get()
copy_count +=1
print('\r进度:%2.f%%'%(copy_count*100/file_count))
if copy_count >= file_count :
break
if __name__ == '__main__':
main()
---------------------------
请输入需要复制的文件夹名字:demo
拷贝的文件名:单线程.py
拷贝的文件名:线程锁.py
进度:25%
进度:50%
拷贝的文件名:进程池.py
拷贝的文件名:进程池间通信.py
进度:75%
进度:100%