对Python中进程概念的理解(1)

多任务

多任务:简单地说,就是操作系统可以同时运行多个任务。

1、一个cpu同一个时刻只能执行一个任务,因为切换速度非常快,感觉是多任务
2、操作系统已经设置好cpu的使用权如何分配,自己写的代码无权干涉
3、任务调度有很多算法,如:1)优先级调度 2)时间轮转 等…

程序和进程

  • 编写完毕的代码,在没有运行的时候,称之为程序
  • 正在运行着的代码,就成为进程

进程,除了包含代码以外,还有需要运行的环境等,所以和程序是有区别的。

fork()函数

当程序执行到os.fork()时,操作系统会创建一个新的进程(子进程),然后复制父进程的所有信息到子进程中。

fork函数,只在Unix/Linux/Mac上运行,windows不可以

父进程和子进程都会从fork()函数中得到一个返回值,在子进程中这个值一定是0,而父进程中是子进程的 id号。

子进程永远返回0,而父进程返回子进程的ID。

  • getpid():获得该进程的ID
  • getppid():获得父进程的ID

多进程中,每个进程中所有数据(包括全局变量)都各有拥有一份,互不影响。
进程
父进程、子进程执行顺序没有规律,完全取决于操作系统的调度算法。

multiprocessing

由于Windows没有fork调用,而Python是跨平台的,自然也应该提供一个跨平台的多进程支持。multiprocessing模块就是跨平台版本的多进程模块。
multiprocessing模块提供了一个Process类来代表一个进程对象。

from multiprocessing import Process
import os


# 子进程要执行的代码
def run_proc(name):
    print('子进程运行中,name= %s ,pid=%d...' % (name, os.getpid()))


if __name__ == '__main__':
    print('父进程 %d.' % os.getpid())
    p = Process(target=run_proc, args=('test',))
    print('子进程将要执行')
    p.start()
    p.join()
    print('子进程已结束')

代码运行结果:
运行结果
创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,这样创建进程比fork()还要简单。
join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步。

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、p = Process(target=run_proc, args=(‘test’,))初始化状态
2、p.start() 就绪状态,一旦获取使用cpu使用权运行,运行状态
3、运行过程中,cpu可能切换走,变成阻塞状态,阻塞状态结束后变成就绪状态,等待获取cpu使用权
4、直到进程的功能函数运行完毕,进程死亡

如果进程中有sleep、input、join也是阻塞状态

创建新的进程还能够使用类的方式,可以自定义一个类,继承Process类,每次实例化这个类的时候,就等同于实例化一个进程对象。

from multiprocessing import Process
from time import sleep
import random
import os


class Sing(Process):
    def run(self):
        for i in range(3):
            print("Sing...%d...%d" % (i, os.getpid()))
            sleep(random.random())


class Dance(Process):
    def run(self):
        for i in range(3):
            print("Dance...%d...%d" % (i, os.getpid()))
            sleep(random.random())


sing = Sing()
sing.start()

dance = Dance()
dance.start()

sleep(random.random())
print("game over...")

代码运行结果:
运行结果

两种方式的对比

1、方法
2、继承类

继承类是以面向对象考虑这个事的,所以业务逻辑复杂,建议使用继承类,更好理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值