多任务编程
概念
操作系统可以同时运⾏多个任务。打个 ⽐⽅,你⼀边在⽤浏览器上⽹,⼀边在听MP3,⼀边在⽤Word赶作业,这就是多任务,⾄少同时有3个任务正在运⾏。还有很多任务悄悄地在后台同时运 ⾏着,只是桌⾯上没有显示⽽已。
单核CPU如何实现“多任务”
操作系统轮流让各个任务交替执⾏,每个任务执⾏0.01秒,这样反复执⾏下去。 表⾯上看,每个任务交替执⾏,但CPU的执⾏速度实在是太快了,感觉就像所有任务都在同时执⾏⼀样。
多核CPU如何实现“多任务”
真正的并⾏执⾏多任务只能在多核CPU上实现,但是,由于任务数量远远多 于CPU的核⼼数量,所以,操作系统也会⾃动把很多任务轮流调度到每个核 ⼼上执⾏。
多进程编程
进程的创建
进程 VS 程序
- 编写完毕的代码,在没有运⾏的时候,称之为程序
- 正在运⾏着的代码,就成为进程
注意: 进程,除了包含代码以外,还有需要运⾏的环境等,所以和程序是有区别的
进程的五状态模型
创建⼦进程
Python的os模块封装了常⻅的系统调⽤,其中就包括fork,可以在Python程 序中轻松创建⼦进程
# encoding=utf-8
"""
Date:2019-07-21 09:48
User:LiYu
Email:liyu_5498@163.com
"""
import os
print('当前进程:', os.getpid())
print('当前进程的父进程:', os.getppid())
print('开始创建子进程...')
p = os.fork()
if p == 0:
print('这是子进程,id是:%s,父进程id是:%s' % (os.getpid(), os.getppid()))
else:
print('这是当前进程,id是:%s,子进程id是:%s' % (os.getpid(), p))
执⾏到os.fork()时,操作系统会创建⼀个新的进程复制⽗进程的所有信息到⼦进程中
普通的函数调⽤,调⽤⼀次,返回⼀次,但是fork()调⽤⼀次,返回两次
⽗进程和⼦进程都会从fork()函数中得到⼀个返回值,⼦进程返回是0,⽽⽗进程中返回⼦进程的 id号
多进程修改全局变量
多进程中,每个进程中所有数据(包括全局变量)都各有拥有⼀份,互不影响
多进程编程
Windows没有fork调⽤,由于Python是跨平台的, multiprocessing模块就是跨平台版本的多进程模块。multiprocessing模块提供了⼀个Process类来代表⼀个进程对象。
Process([group [, target [, name [, args [, kwargs]]]]])
target:表示这个进程实例所调⽤对象;
args:表示调⽤对象的位置参数元组;
kwargs:表示调⽤对象的关键字参数字典;
name:为当前进程实例的别名;
group:⼤多数情况下⽤不到;
Process类常⽤⽅法:
is_alive():判断进程实例是否还在执⾏;
join([timeout]):是否等待进程实例执⾏结束,或等待多少秒;
start():启动进程实例(创建⼦进程);
run(): 如果没有给定target参数,对这个对象调⽤start()⽅法时,就将执⾏对象中的run()⽅法;
terminate():不管任务是否完成,⽴即终⽌;
Process类常⽤属性:
name:当前进程实例别名,默认Process-N,N为从1开始计数;
pid:当前进程实例的PID值;
多进程编程方法1: 实例化对象
# encoding=utf-8
"""
Date:2019-07-21 10:15
User:LiYu
Email:liyu_5498@163.com
"""
from multiprocessing import Process
import time
def task1():
print('任务1')
time.sleep(1)
def task2():
print('任务2')
time.sleep(0.5)
def no_multi():
for i in range(3):
task1()
for i in range(5):
task2()
def use_multi():
processess = []
for i in range(3):
p = Process(target=task1)
p.start()
processess.append(p)
for i in range(5):
p = Process(target=task2)
p.start()
processess.append(p)
[processe.join() for processe in processess]
if __name__ == '__main__':
startTime = time.time()
# no_multi()
use_multi()
endTime = time.time()
print(endTime - startTime)