zoukankan      html  css  js  c++  java
  • 【python进阶】深入理解系统进程1

    前言

    之前程序执⾏都是⼀条腿⾛路,甚⾄是⽤⼀杆枪来打天下。

    通过系统编程的学习,会让⼤家有“多条腿”⼀起⾛路,就好⽐有了⼀把机关枪。

    此篇为深入理解进程第一篇,下面开始今天的说明~~~

    多任务的引入

    现实生活中

    有很多的场景中的事情是同时进⾏的,⽐如开⻋的时候⼿和脚共同来驾驶汽⻋,再⽐如唱歌跳舞也是同时进⾏的;
    如下视频是:迈克杰克逊的⼀段视频:

    http://v.youku.com/v_show/id_XMzE5NjEzNjA0.html

    试想,如果把唱歌和跳舞这2件事情分开依次完成的话,估计就没有那么好的效果了(想⼀下场景:先唱歌,然后在跳舞,O(∩_∩)O哈哈~)

    程序中

    如下程序,来模拟“唱歌跳舞”这件事情

    from time import sleep
    
    def sing():
        for i in range(3):
            print("正在唱歌...%d"%i)
            sleep(1)
    
    def dance():
        for i in range(3):
            print("正在跳舞...%d"%i)
            sleep(1)
    
    if __name__ == '__main__':
        sing()#唱歌
        dance()#跳舞

    运行结果如下:

    !!!注意:

    • 很显然刚刚的程序并没有完成唱歌和跳舞同时进⾏的要求 
    • 如果想要实现“唱歌跳舞”同时进⾏,那么就需要⼀个新的⽅法,叫做:多任务

    多任务的概念

    什么叫“多任务”呢?简单地说,就是操作系统可以同时运⾏多个任务。打个⽐⽅,你⼀边在⽤浏览器上⽹,⼀边在听MP3,⼀边在⽤Word赶作业,这就 是多任务,⾄少同时有3个任务正在运⾏。还有很多任务悄悄地在后台同时运⾏着,只是桌⾯上没有显示⽽已。

    现在,多核CPU已经⾮常普及了,但是,即使过去的单核CPU,也可以执⾏多任务。由于CPU执⾏代码都是顺序执⾏的,那么,单核CPU是怎么执⾏多任务的呢?
    答案就是操作系统轮流让各个任务交替执⾏,任务1执⾏0.01秒,切换到任务2,任务2执⾏0.01秒,再切换到任务3,执⾏0.01秒……这样反复执⾏下去。 表⾯上看,每个任务都是交替执⾏的,但是,由于CPU的执⾏速度实在是太快了,我们感觉就像所有任务都在同时执⾏⼀样。

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

    进程的创建-fork 

    1. 进程 VS 程序

    编写完毕的代码,在没有运⾏的时候,称之为程序
    正在运⾏着的代码,就成为进程
    进程,除了包含代码以外,还有需要运⾏的环境等,所以和程序是有区别的。

    2. fork( )

    Python的os模块封装了常⻅的系统调⽤,其中就包括fork,可以在Python程 序中轻松创建⼦进程:

    import os
    
    # 注意:fork函数,只在Unix/Linux/Mac上运行,windows不可以
    pid = os.fork()
    
    if pid == 0:
        print('哈哈1')
    else:
        print('哈哈2')

    运行结果:

    说明:

    • 程序执⾏到os.fork()时,操作系统会创建⼀个新的进程(⼦进程),然后复制⽗进程的所有信息到⼦进程中 
    • 然后⽗进程和⼦进程都会从fork()函数中得到⼀个返回值,在⼦进程中这 个值⼀定是0,⽽⽗进程中是⼦进程的id号

    在Unix/Linux操作系统中,提供了⼀个fork()系统函数,它⾮常特殊。
    普通的函数调⽤,调⽤⼀次,返回⼀次,但是fork()调⽤⼀次,返回两次,因 为操作系统⾃动把当前进程(称为⽗进程)复制了⼀份(称为⼦进程),然 后,分别在⽗进程和⼦进程内返回。
    ⼦进程永远返回0,⽽⽗进程返回⼦进程的ID。
    这样做的理由是,⼀个⽗进程可以fork出很多⼦进程,所以,⽗进程要记下 每个⼦进程的ID,⽽⼦进程只需要调⽤getppid()就可以拿到⽗进程的ID。

    3. getpid()、getppid()

    import os
    
    rpid = os.fork()
    if rpid<0:
        print("fork调用失败。")
    elif rpid == 0:
        print("我是子进程(%s),我的父进程是(%s)"%(os.getpid(),os.getppid()))
        x+=1
    else:
        print("我是父进程(%s),我的子进程是(%s)"%(os.getpid(),rpid))
    
    print("父子进程都可以执行这里的代码")

    运⾏结果:

    多进程修改全局变量

    import os
    import time 
    
    num = 0
    
    #注意:fork函数,只在Unix/Linux/Mac上运行,windows不可以
    pid = os.fork()
    
    if pid == 0:
        num+=1
        print("哈哈1---num=%d"%num)
    
    else:
        time.sleep(1)
        num+=1
        print("哈哈2---num=%d"%num)

    运行结果:

    总结:

    多进程中,每个进程中所有数据(包括全局变量)都各有拥有⼀份,互不影响

    多次fork问题

    如果在⼀个程序,有2次的fork函数调⽤,是否就会有3个进程呢?

    import os
    import time
    
    # 注意,fork函数,只在Unix/Linux/Mac上运行,windows不可以
    pid = os.fork()
    if pid == 0:
        print('哈哈1')
    else:
        print('哈哈2')
    
    pid = os.fork()
    if pid == 0:
        print('哈哈3')
    else:
        print('哈哈4')
    
    time.sleep(1)

    运行结果:

    说明:

    ⽗⼦进程的执⾏顺序

    ⽗进程、⼦进程执⾏顺序没有规律,完全取决于操作系统的调度算法

  • 相关阅读:
    题解 [APIO2014]连珠线
    题解 [ZJOI2019]语言
    题解 Hero meet devil
    题解 [BJOI2019]奥术神杖
    题解「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set
    题解 Sue的小球/名次排序问题/方块消除/奥运物流
    题解 「一本通 5.4 练习 1」涂抹果酱
    Mybatis的类型转换
    面试题:微服务熔断降级限流
    面试题:微服务网关
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/9014716.html
Copyright © 2011-2022 走看看