进程篇
(最近在学习进程,看视频的时候做了一个总结)
现代操作系统(Window、Mac OS X、Unix、Linux)都支持‘多任务’
什么叫做多任务呢?
--> 操作系统可以同时运行多个任务
-->单核CPU执行多任务是时间片轮转实现的(操作系统轮流让各个任务交替执行)
-->多核CPU,每个核心执行一个进程,如果进程比较多,那就有可能其中一个交替执行;但是进程数量一定比核心数多,所以操作系统会自动把很多任务轮流调度到每个核心上执行
并发:看上去一起执行,任务数多余CPU核心数
并行:真正一起执行,任务数小于等于CPU核心数
实现多任务的方式:
1.多进程模式
扫描二维码关注公众号,回复:
4619848 查看本文章
2.多线程模式
3.协程模式
4.多进程+多线程模式
# 多任务同时进行
# 在写多进程代码的时候要先调用一个多进程类下的一个进程函数 from multiprocessing import Process import time, os # 定义一个子进程函数,传一个参数 def run(string): # 写一个死循环用来测试 while True: # 打印子循环的信息 # getpid()当前进程的ID号 # getppid()当前进程的父进程的ID号 print('zpstu----{}----{}----{}'.format(string, os.getpid, os.getppid())) time.sleep(1) if __name__ == '__main__': print('主进程开始启动了-{}'.format(os.getpid())) # 创建子进程,target指明进程执行的任务 p = Process(target=run, args=('zpatu',)) # 启动进程 p.start() while True: print('zpstu is very good!') time.sleep(1)
# 进程、子进程、执行顺序
'''
进程:对于操作系统而言,一个任务就是一个进程;进程是系统中程序执行和资源分配的基本单位i,每个进程都有自己的数据段、代码段、和堆栈段
'''
from multiprocessing import Process import time, os
def run(string):
print('子进程启动')
# 等待两秒
time.sleep(2)
print('子进程结束')
if __name__ == '__main__':
# 首先父进程启动
print('父进程启动')
# 创建子进程
p = Process(target=run, args=('zpstu',))
# 启动进程
p = start()
# 等待子进程结束,在结束父进程
p.join() # join()必须要等子进程结束了,在执行父进程,不然就卡这里了
print('父进程结束')
# 全局变量在多个进程中不能共享
'''
父进程和子进程之间的资源是不能共享的,就算使用全局global属性,也是不能共享
这是因为:在子进程创建的时候,对全局变量做了一个备份,所以num两个变量就不是一个变量
'''
from multiprocessing import Process
from time import sleep
num = 100
def run():
print('启动子进程')
global num # 这行代码就相当于num = 100
num += 1
print('子进程结束')
if __name__ == '__main__':
print('父进程开始')
p = Process(target=run)
p.start()
p.join()
print('父进程结束-->{}'.format(num))
# 启动大量子进程
'''
这里引入了进程池的概念
'''
from multiprocessing import Pool
import os,time,random
def run():
print('子进程{}启动-->{}'.format(name, os.getpid()))
start = time.time()
time.sleep(random.choice([1, 2, 3]))
end = time.time()
print('子进程{}结束-->{}'.format(name, os.getpid()))
if __name__ == '__main__':
print('父进程启动')
# 创建多个进程
# 进程池:便是可以同时执行的进程数量
# Pool默认大小是CPU核心数
pp = Pool(5)
for i in range(5):
# 创建进程,放入进程池统一管理(当你放入进程池的时候,进程便开始启动了)
pp.apply_async(run, args=(i,))
# 再调用join之前,必须调用close,调用close之后就不能再继续添加新的进程了
pp.close()
# 进程池对象调用join,他会等待进程池所有的子进程结束完毕再去结束父进程
pp.join()
print('父进程结束')
# 拷贝文件(普通的拷贝文件,下面有多进程的拷贝文件)
import os, time
from multiprocessing import Pool
# 拷贝文件的函数
def copyFile(rPath, wPath):
fr = open(rPath, 'rb')
fw = open(wPath, 'wb')
content = fr.read()
fw.write(content)
fr.close()
fw.close()
# 两个文件路径
path = r'E:\code\aaa'
topath = r'E:\code\toFile'
# 读取path下的所有文件
fileList = os.listdir(path)
# 启动for循环处理每一个文件
start = time.time()
foe i in fileList:
copyFile(os.path.join(path, i), os.path.join(topath, i))
end = time.time()
print('总耗时:{:0.2}'.format(end-start))
# 多进程实现文件拷贝
import os, time
from multiprocessing import Pool
def copyFile(rPath, wPath):
fr = open(rPant, 'rb')
fw = open(wPath, 'wb')
content = fr.read()
fw.write(content)
fr.close()
fw.close()
path = r'E:\code\aaa'
topath = r'E:\code\toFile'
if __name__ == '__main__':
fileList = os.listdir(path)
start = time.time()
for i in fileList:
# 拼接目录
pp.apply_async(copyFile, args=(os.path.join(path, i)))
pp.close()
pp.join()
end = time.time()
print('总耗时{:0.2}'.format(end-start))
# 进程间通信
from multiprocessing import Process, Queue
import os,time
def write(q):
print('启动写入子进程--{}'.format(os.getpid()))
for i in ['A', 'B', 'C', 'D', 'E']:
q.put(chr)
time.sleep(1)
print('结束写入子进程')
def read(q):
print('启动读取子进程--{}'.format(os.getpid()))
while True:
value = q.get(True)
print('value = ', value)
print('结束读取子进程') # 这行代码不会执行,因为死循环根本就出不来,只能强制结束它
if __name__ == '__main__':
# 父进程创建队列,并传递给子进程
# 考录队列,拿出来一个就没一个,也就是一个传递进去,一个拿出来
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
pw.start()
pr.start()
pw.join()
# pr进程内是一个死循环,无法等待结束,所以只能强行结束
pr.terminate()
print('父进程结束')