Python中的进程

Python中的进程

1、单任务和多任务
  • 单任务:一次做一件事件,前一件事情做完,才开始下一件事情
  • 多任务:同时做多件事情,多件事情可以同时处理。
2、单核CPU的多任务
  • 时间片:CPU执行时间分割成小段
3、并行和并发
  • 并行:m个任务在m个处理器运算核心上执行
  • 并发:m个任务在n个处理器运算核心上执行,m>n
4、程序和进程
  • 程序:存放代码的可执行文件,静态的
  • 进程:运行中的程序,进程需要相应的系统资源:内存、时间片、pid。动态的
5、fork

​ Python中的OS模块封装了常见的系统调用,可以使用OS模块中的fork()方法来创建新的进程

  • fork只能在linux/unix系统中使用,windows中是不可以的
  • 当程序执行os.fork()时,系统会创建出一个新的进程(子进程),然后复制父进程中的所有内容到子进程中。
  • 父进程、子进程都会从fork()函数中得到一个返回值。
    • 父进程,得到子进程的pid
    • 子进程,得到返回值0
import os


def main():
    pid = os.fork()

    if pid > 0:
        print("父进程---Hello")
    elif pid == 0:
        print("子进程---world")


if __name__ == "__main__":
    main()

​ 运行结果:

父进程---Hello
子进程---world
6、多进程中的全局变量
import os

import time

num = 10
# 全局变量在多进程中,每个进程拥有的数据(包括全局变量)各有一份,是互不相关的
# 在父进程中,我们通过global改变了全局变量num的值,但是在子进程中,还是之前没有改变的num的值


def sing():
    global num
    for temp in range(3):
        print("----sing--num:%d---pid:%d--ppid:%d" % (num, os.getpid(), os.getppid()))
        num += 1
        time.sleep(1)


def dance():
    for i in range(3):
        print("------dance--num:%d--pid:%d,ppid:%d" % (num, os.getpid(), os.getppid()))
        time.sleep(1)


def main():

    pid = os.fork()

    if pid > 0:
        sing()
    elif pid == 0:
        dance()

if __name__ == "__main__":
    main()

​ 运行结果:

----sing--num:10---pid:32922--ppid:20979
------dance--num:10--pid:32927,ppid:32922
----sing--num:11---pid:32922--ppid:20979
------dance--num:10--pid:32927,ppid:32922
----sing--num:12---pid:32922--ppid:20979
------dance--num:10--pid:32927,ppid:32922

总结:

在多进程中,每个进程中有的数据(包括全局变量),各有一份,在父进程中通过global改变了全局变量,在子进程中全局变量还是之前的值,不会改变。

父进程、子进程执行的顺序是没有规律的,完全取决于操作系统的调度算法

7、getpid和getppid
  • os.getpid(): 获取当前进程的pid
  • os.getppid(): 获取当前进程父进程的pid,即ppid
8、使用Process创建多进程

​ 上面提到os.fork()不能在Windows下运行,那么既然说Python是一门跨平台的语言,那我们怎么在Windows平台下使用多进程呢?答案就是使用Process。

​ 使用Process创建多进程的流程:

  • 首先导入Process

    form multiprocessing import Process

  • 创建一个Process对象

    p = Process() # 参数等会结合Demo讲解

  • 启动进程

    p.start() # 进程不启动,没有pid,但是会有进程名

  • 结束进程

    p.terminate()

    p.join() # 导致父进程阻塞,等待子进程结束,并回收资源

  • 创建Process对象时,可传递的参数:

    p = Process(target=XXX, args=(元组), kwargs={key:value})

    target = XXX 指定的任务函数

    args = (元组) 、kwargs={key:value} 给任务函数传递的参数

  • 判断进程是否在运行了

    p.is_alive() # True表示在运行 False表示未运行

    Demo

    import os
    from multiprocessing import Process
    
    
    def myTask():
    for i in range(5):
        print("子进程进程:%d --------%d" % (os.getpid(), i))
    
    
    def main():
    
    print("父进程:%d" % os.getpid())
    
    # 创建一个进程
    
    p = Process(target=myTask)
    
    
    # 启动进程
    
    p.start()
    
    # 阻塞父进程,等待子进程结束,并回收哦资源
    
    p.join()
    
    if __name__ == '__main__':
    main()
    
9、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值

10、使用Process子类创建进程

​ 这就关系到了之前的面向对象中的继承,我们来写程序,来使用 Process的子类来创建进程。

​ Demo:

import os
from multiprocessing import Process

import time

"""
    Process类本身也有__init__方法,这个子类相当于重写了这个方法
    但是这样有一个问题,我们并没有完全的初始化一个Process类,所以就不能从这个类中继承一些方法和属性
    最好的方法就是在__init__方法中奖继承类本身传递给Process.__init__方法,完成初始化操作
"""


class MyProcess(Process):
    def __init__(self):
        Process.__init__(self)

    def run(self):
        """要执行的任务代码写在run方法中"""
        for i in range(5):
            print("子进程:%d,正在运行。。。%d" % (os.getpid(), i))
            time.sleep(1)


def main():
    print("父进程:%d,正在运行。。。" % os.getpid())
    p = MyProcess()
    p.start()
    p.join()


if __name__ == '__main__':
    main()

​ 运行结果:

父进程:16836,正在运行。。。
子进程:13432,正在运行。。。0
子进程:13432,正在运行。。。1
子进程:13432,正在运行。。。2
子进程:13432,正在运行。。。3
子进程:13432,正在运行。。。4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值