一、进程和程序
进程:正在执行的程序
程序:没有执行的代码,是一个静态的
进程的状态
1 使用进程实现多任务
multiprocessing模块就是跨平台的多进程模块,提供了一个Process类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另外的事情。
2 线程和进程之间的对比
- 进程:能够完成多任务,一台电脑上可以同时运行多个QQ
- 线程:能够完成多任务,一个QQ中的多个聊天窗口
- 根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位
3 进程间通信-Queue
Queue-队列 先进先出
import multiprocessing
def download(q):
'''下载数据'''
lis = [11, 22, 33]
for item in lis:
q.put_nowait(item)
print('下载完成,并保存在队列。。。。')
def analysis(q):
"""数据处理"""
analysis_data = list()
while True:
data = q.get()
analysis_data.append(data)
if q.empty():
break
print(analysis_data)
def main():
# 创建队列
q = multiprocessing.Queue()
t1 = multiprocessing.Process(target=download, args=(q, ))
t2 = multiprocessing.Process(target=analysis, args=(q, ))
t1.start()
t2.start()
if __name__ == '__main__':
main()
多进程共享全局变量
4 进程池
当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但是如果是上百甚至上千个目标,手动的去创建的进程的工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法
import multiprocessing
def demo1(q):
# 进程池里面的进程 如果出现异常 不会主动抛出 自己写一个抛出异常
try:
q.put('a')
except Exception as e:
print(e)
def demo2(q):
try:
data = q.get()
print(data)
except Exception as e:
print(e)
if __name__ == '__main__':
# q = Queue() 这个不能完成进程之间的通信
# q = multiprocessing.Queue() # 可以进程间通信
q = multiprocessing.Manager().Queue() # 可以完成 进程池中的通信
# 创建进程池
po = multiprocessing.Pool(2)
po.apply_async(demo1,args=(q,))
po.apply_async(demo2,args=(q,))
po.close()
po.join()
5 多任务文件夹复制
"""
思路:
多任务文件夹复制
1、获取用户要复制文件夹名字
2、创建一个新的文件夹
3、获取原文件夹的所有待拷贝的文件名字
4、创建进程池
5、添加拷贝任务
"""
import multiprocessing
import os
def copy_file(file_name, new_folder_name, old_folder_name):
"""完成文件拷贝"""
print('拷贝文件名称是:%s' % file_name)
with open(old_folder_name + '/' + file_name, 'rb') as f:
content = f.read()
f.close()
# old_file = open(old_folder_name + '/' + file_name, 'rb')
# content = old_file.read()
# old_file.close()
# 6 保存新的文件夹中
with open(new_folder_name + '/' + file_name, 'wb') as f:
f.write(content)
f.close()
# new_file = open(new_folder_name + '/' + file_name, 'wb')
# new_file.write(content)
# new_file.close()
def main():
# 1 获取用户要复制文件夹名字
old_folder_name = input('请输入要复制文件夹名字:')
# 2 创建一个新的文件夹
new_folder_name = old_folder_name + '【复件】'
# 2.1 判断文件夹是否存在,不存在则创建,存在创建会报错
if not os.path.exists(new_folder_name):
os.mkdir(new_folder_name)
# 3 获取原文件夹的所有待拷贝的文件名字
file_names = os.listdir(old_folder_name)
# print(file_names)
# 4 创建进程池
po = multiprocessing.Pool(5)
# 5 添加拷贝任务
for file_name in file_names:
po.apply_async(copy_file, args=(file_name, new_folder_name, old_folder_name))
po.close()
po.join()
if __name__ == '__main__':
main()