python -- 多任务编程

一、 多任务编程

多任务含义

就是操作系统可以同时运⾏多个任务。
现实中的多任务比如:手机上边听音乐边聊天,电脑上多个软件同时运行

单核CPU实现多任务

操作系统轮流让各个任务交替执⾏,每个任务执⾏0.01秒,这样反复执⾏下去。 表⾯上看,每个任务交替执⾏,但CPU的执⾏速度实在是太快了,感觉就像所有任务都在同时执⾏⼀样
逻辑上表现为:各个任务并发执行,即一个任务执行几秒后执行另一个任务,来回交替(同时运行,但是每个时间段只有一个任务执行)
物理上表现为:各个任务串行执行(第一个任务执行完之后再执行第二个任务)
在这里插入图片描述

多核CPU实现“多任务”

真正的并⾏执⾏多任务只能在多核CPU上实现,但是,由于任务数量远远多 于CPU的核⼼数量,所以,操作系统也会⾃动把很多任务轮流调度到每个核 ⼼上执⾏。
在这里插入图片描述

二、多进程编程

几个概念:
多进程编程:一个任务交给多个cpu
程序:编写完毕的代码,在没有运⾏的时候,称之为程序
进程:正在运⾏着的代码(程序),就成为进程
注意: 进程,除了包含代码以外,还有需要运⾏的环境等,所以和程序是有区别的
进程状态: 创建(created)-----就绪(ready)-----运行(running)-----阻塞(waiting)-----结束(terminated)

  • 进程运行中cpu执行其他任务,造成进程中断,进入就绪状态,等待cpu分配时间片段
  • 进行运行中需要等待一个输入,进入阻塞状态,接受输入,进入就绪阶段,等待cpu分配时间片段来running。在阻塞状态下让子进程去进行干其他事情,不浪费时间片段就是多进程编程。

在这里插入图片描述

创建进程

为什么需要多进程:当进入阻塞状态等待接受其他信息才能运行时,此时间片段浪费,可以进行其他任务使得时间合理化
多进程的条件:创建子进程

  • Python的os模块中的fork()函数,用来创建子进程但是只能用在linux系统中
    在这里插入图片描述
    fork()函数理解
    执⾏到os.fork()时,操作系统会创建⼀个新的进程复制⽗进程的所有信息到⼦进程中
    普通的函数调⽤,调⽤⼀次,返回⼀次,但是fork()调⽤⼀次,返回两次
    ⽗进程和⼦进程都会从fork()函数中得到⼀个返回值,⼦进程返回是0,⽽⽗进程中返回⼦进程的 id号,由于父进程会有许多子进程,为了记录父进程新加入的子进程需要在父进程中返回一个子进程的ID
    思考问题:
    fork拷贝父进程来创建子进程,修改全局变量,两个进程之间会有影响吗? fork到底对父进程拷贝了什么?
    :多进程修改全局变量,多进程中,每个进程中所有数据(包括全局变量)都各有拥有⼀份,父、子进程在内存的不同区域存储互不影响。
#  将当前进程使用fork拷贝一份子进程,同时在当前进程中定义一个全局变量money,在子进程中修改全局变量money,对比当前进程(父进程)与子进程的全局变量的值是否发生变化。


import os
import time

# 定义一个全局变量money
money = 100
print('当前进程pid:',os.getpid())
#为了更清楚的看到进程,让程序休眠
print('当前进程父id:',os.getppid()) #父进程为程序运行的大环境:pycharm
time.sleep(5)

p0bj=os.fork() #执行fork函数时:操作系统会将当前进程所有信息拷贝到⼦进程中
#fork()调⽤⼀次,返回两次
#⽗进程和⼦进程都会从fork()函数中得到⼀个返回值,⼦进程返回是0,⽽⽗进程中返回⼦进程的id号,用于记录父进程新创建的子进程
#⼦进程返回是0
if p0bj==0:
    money = 200
    print("子进程返回的信息, money=%d" % (money))
#⽗进程中返回⼦进程的pid
else:
    print('创建子进程%s,父进程为%d'%(p0bj,os.getppid()))
    print(money)




#执行结果:
创建子进程2508,父进程为11528
100
子进程返回的信息, money=200
  • 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值

windows下多进程编程方法1: 实例化对象用于产生一个子进程。
Process:类
target参数:表示这个进程实例所调⽤对象;子进程要执行的任务

import time
from multiprocessing  import Process

def task1(): #定义两个任务
    print("正在听音乐")
    time.sleep(1)
def task2():
    print("正在编程......")
    time.sleep(0.5)

def use_multi(): #使用多进程,需要在任务外部执行join
    processes=[] #将所有任务创建好,再执行join等待
    for i in range(2): #来一个任务开一个进程,多个任务用多个进程同时执行
        p1 = Process(target=task1) #产生一个子进程,执行任务1
        p1.start() #子进程执行任务
        processes.append(p1)
    for i in range(5):
        p2 = Process(target=task2)
        p2.start()
        processes.append(p2)
     
        #所有子进程任务创建好开始后,等待每一个进程的任务结束。
        #开始第一个子进程的同时其他进程也在执行,直到一个一个的子进程全部结束
    [process.join() for process in processes] 主进程阻塞,执行子进程,结束后再执行主进程。

if __name__ == '__main__':
    # 主进程
    start_time= time.time()
    use_multi()
    end_time = time.time()
    print(end_time-start_time)
#3个进程同时执行:主进程、p1、p2, 并行
# 为了等两个子进程执行完后再执行主进
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值