zoukankan      html  css  js  c++  java
  • 获取进程以及父进程的pid 验证进程之间的数据隔离 join方法 进程对象的其他属性 僵尸进程与孤儿进程(存在Linux系统中) 守护进程

    day32

    一丶获取进程以及父进程的pid

    含义:

    进程在内存中开启多个,操作系统如何区分这些进程,每个进程都有一个唯一表示

    方法三种方法:

    一,终端查看所有pid tasklist

    二,指定具体的PID tasklist | findstr python

    三,代码查看pid os 模块

    ### 利用os 模块 查看 pid(当前进程id)  和 ppid(父进程id)

    import os
    import time
    print('子进程pid:',os.getpid())  # 查看当前python程序的pid
    print('父进程pid:',os.getppid()) #pycharm的pid
    time.sleep(100)

     

    二丶验证进程之间的数据隔离

    验证数据隔离

    如果主进程中x的值是否改变,没有改变则说明父进程与子进程之间数据隔离

    # -*-coding:utf-8-*-
    # Author:Ds
    from multiprocessing import Process
    x=1000
    def task():
       global x  # 引用成全局变量
       x=2       # 修改全局变量( 由于数据隔离,修改的数据只存在子进程中)


    if __name__ == '__main__':
       p1=Process(target=task,)
       p1.start()
       
       # 如果x的值没有改变,说明父进程与子进程之间数据隔离
       print(f'主进程中的x的变量:{x}')

    验证数据延用

    只有数字能被沿用,范围:-5~256, 主进程子进程是沿用同一个.字符串等其他数据类型不延用

    # -*-coding:utf-8-*-
    # Author:Ds
    from multiprocessing import Process
    import time
    x=100
    def task():
       print(f'子进程中:{id(x)}')

    if __name__ == '__main__':
       # 子进程与父进程之间的空间隔离., 要验证初始变量是否是一个id.
       print(f'主进程中:{id(x)}')
       p1=Process(target=task,)
       p1.start()
       time.sleep(3)

     

    三丶join方法

    含义:

    join进程等待,等待主进程等待子进程结束之后再执行.不会被夯住(不会卡住)

    ###  并行 , 一共执行3秒. (前提是你已经创建3个子进程)
    #原因:1. start方法 只是告诉主进程, 开启一个子线程.
        # 2. join方法是等待
    from multiprocessing import  Process
    import time
    def task(name,sec):
       print(f'{name}is running')
       time.sleep(sec)
       print(f'{name} is done')

       
    if __name__ == '__main__':
       start_time=time.time()   #记录程序开始运行时间

       p1=Process(target=task,args=('alex',1))
       p2=Process(target=task,args=('abc',2))
       p3=Process(target=task,args=('ds',3))

       # 现在内存中几乎同时创建了3个子进程
       # 随机性,创建子线程时间可能不同. 操作系统调用cpu先运行谁,谁先执行.
       p1.start()
       p2.start()
       p3.start()

       ### 相当于: 现在内存中存在3个任务,同时进行,第一个任务执行1秒停顿, join方法,. 第二个任务已经执行了1秒,再执行1秒.over.第三个任务已经执行2秒停顿.再执行1秒.over.
       
     
       p1.join() # 通知cpu 等待子进程执行完就执行主进程
       p2.join() # 通知cpu 等待子进程执行完就执行主进程
       p3.join() # 通知cpu 等待子进程执行完就执行主进程
       ### 以最时间长的为标准. 执行完子进程再执行父进程的打印.
       
       print(f'执行总时长:{time.time()-start_time}')
       
       
    ### 总结: 三次start开启了三个通道.同时进行join 只是通知cpu要等待子进程执行完毕,再执行主进程





    ### for循环简化上述代码:  

    from multiprocessing import  Process
    import time

    def task(name,sec):
       print(f'{name}is running')
       time.sleep(sec)
       print(f'{name} is done')

       
    if __name__ == '__main__':
       start_time=time.time()
       p_l=[]   # 把子线程对象,放在列表中
       for e in range(1,4):
           e=Process(target=task,args=('alex',3))
           e.start()
           p_l.append(e)
       for i in p_l:
           i.join()
       print(f'{time.time()-start_time}')
    ### join 串行
    from multiprocessing import  Process
    import time
    def task(name,sec):
       print(f'{name} is running')
       time.sleep(sec)
       print(f'{name} is done')

    if __name__ == '__main__':
       start_time=time.time()

       p1=Process(target=task,args=('alex',1))
       p2=Process(target=task,args=('abc',2))
       p3=Process(target=task,args=('ds',3))

       p1.start() # 先创建p1 子进程并执行
       p1.join() # 通知cpu 等待子进程执行完毕,再执行主进程

       p2.start() # 等待p1执行完毕在开启p2进程
       p2.join()

       p3.start() # 等待p1.p2执行完毕在开启p3进程
       p3.join()
       
       # 最少6秒,还有系统调度cpu创建进程时间,往往高于6秒
       print(f'执行总时长:{time.time()-start_time}')
       
       
    ### 总结: 一次 start 一次 join 相当于开了一个通道. 只能一次过以一辆车. join通知cpu等待子进程完成后才能继续执行主进程

     

    四丶进程对象的其他属性

    常见的属性:

    pid:获取子进程id

    name:获取子进程name属性

    terminate:杀死子进程

    is_alive:查看子进程是否还活着

    # -*-coding:utf-8-*-
    # Author:Ds

    from multiprocessing import Process
    import time

    def task():
       print('子线程 is running')

    if __name__ == '__main__':
       p=Process(target=task,name='任务1')
       p.start()

       print(p.pid) # 获取子进程的pid
       print(p.name) # 获取子进程的name属性
     
       p.terminate()   # 杀死进程 :通知操作系统执行当前任务(耗时)
       time.sleep(1) # 由于is_alive存在主进程中.所以需要睡1秒之后再进行查看
       
       print(p.is_alive())
       print('主进程')

     

    五丶僵尸进程与孤儿进程(存在Linux系统中)

    进程了解:

    每个进程退出时,内核释放应该进程所有的资源,但是还会保留一部分的信息,如:进程号,进程状态,运行时间.直到主进程利用这个waitepid()方法,才能够完全释放,回收子进程的资源

     

    僵尸进程:(有害)

    主进程(父进程)不能正常的使用waitepid()方法对子进程进行资源回收,这个状态是僵尸状态(Z状态).那么这部分的子进程就会成为僵尸进程

    每一次子进程结束前,都会有一个僵尸状态.直到父进程调用waitepid()才会从僵尸态到消亡态

    僵尸进程的害处:

    僵尸进程的资源无法被释放,长期占用.内存压力增大.当新的程序来处理时,则会因为资源不足而导致运行失败.

    kill -9 pid 是杀不死僵尸进程的,他能将进程的状态从正在运行态变成僵尸态,却不能将僵尸态的进程变为消亡态

    # -*-coding:utf-8-*-
    # Author:Ds

    #### 父进程不能给子进程收尸 ,子进程就是僵尸进程

    from multiprocessing import Process
    import time
    import os

    def task(name):

       print(f'{name} is running')
       print(f'子进程开始了:{os.getpid()}')
       time.sleep(50)


    if __name__ == '__main__':
       for i in range(100000):
           p = Process(target=task,args=('怼哥',))
           p.start()
       print(f'33[1;35;0m 主进程:{os.getpid()}33[0m')

     

    孤儿进程:

    父进程已经挂掉了,子进程还在运行.这个子进程就是孤儿进程. 孤儿进程会被'init'进程回收

    from multiprocessing import Process
    import time
    import os

    def task(name):

       for i in  range(20):
           time.sleep(0.5)
           print(f'子进程开始了:{os.getpid()}')


    if __name__ == '__main__':
       p = Process(target=task,args=('怼哥',))
       p.start()
       time.sleep(3)
       print(f'33[1;35;0m 主进程:{os.getpid()}33[0m')
     

    # 父进程 正常对退出,子进程还有自己的事情没有干完. 所以子进程成为孤儿进程

     

    六丶守护进程

    含义:

    守护进程本身是一个子进程,守护的主进程

    结束条件:主进程代码结束了,守护进程也就结束了

    ### 守护进程也属于子进程,先于主进程代码结束前结束.因为主进程要回收子进程的资源
    
    # 1. 主进程的代码结束,守护进程结束
    
    # 2. 主进程要回收守护进程(子进程)的资源
    
    # 3. 等待其他所有子进程结束
    
    # 4. 主进程回收所有子进程资源
    
    # -*-coding:utf-8-*-
    # Author:Ds
    from multiprocessing import Process
    import time
    import os
    
    def task(name):
    
        for i in  range(20):
            time.sleep(0.5)
            print(f'子进程开始了:{os.getpid()}')
    
    
    def func2():
        print('start:func2')
        time.sleep(5)
        print('end:func2')
    
    if __name__ == '__main__':
        start_time=time.time()
        p = Process(target=task,args=('怼哥',))
        p.daemon=True #  设置为守护进程
        p.start()
        Process(target=func2).start()
        print('in main')
        time.sleep(3)
        print(f'主进程开始了:{os.getpid()}  ,结束时间{time.time()-start_time}')
        
    
    
    
    ### 为什么要有主进程等待子进程结束之后才结束呢?
        # 1.因为主进程负责给子进程回收一些系统资源
    
    ### 守护进程:本身是一个子进程,守护的主进程
        # 结束条件:主进程代码结束了,守护进程也就结束了
    ### 进程
        # 主进程的代码结束,守护进程结束
        # 主进程要回收守护进程(子进程)的资源
        # 等待其他所有子进程结束
        # 主进程回收所有子进程资源
    
  • 相关阅读:
    系统维护相关问题
    Python环境维护
    哈希表解决字符串问题
    论文笔记二:《A Tutoral on Spectral Clustering》
    论文笔记之哈希学习比较--《Supervised Hashing with Kernels》《Towards Optimal Binary Code Learning via Ordinal Embedding》《Top Rank Supervised Binary Coding for Visual Search》
    Java中String、StringBuffer、StringBuilder的比较与源 代码分析
    浙大pat1040 Longest Symmetric String(25 分)
    浙大pat1039 Course List for Student(25 分)
    浙大pat---1036 Boys vs Girls (25)
    百炼oj-4151:电影节
  • 原文地址:https://www.cnblogs.com/xiangwang1/p/12180110.html
Copyright © 2011-2022 走看看