zoukankan      html  css  js  c++  java
  • 进程&进程池

    进程

    服务器中, s.listen(n) n不能无限大,以为内存不可能无限大,n表示内存同一时间接纳的等待连接数,可以看成一个(队列),取出一个拿去建立连接,然后再放进一个,队列中一直保持n个连接

    请求.

    补充一点:
      print() 是计算操作, 计算机中除了IO,都是计算(PS:cpu干的活都是计算).

    进程的运行回收机制: 主进程等子进程运行完 才回收子进程,自己再关闭

    父进程杀死了,子进程就会变成孤儿进程(甚至变成僵尸进程)

    非常重要的一个概念:
      运行py文件,在进程中显示的不是xx.py, 而是解释器的python.exe,
      是因为代码只是一堆符号,没有意义,只有把代码传给python解释器,python解释器解释后,调用的python解释器的功能.
      实际上用的python解释器的功能,所以进程中显示运行的是python.exe解释器而不是xx.py文件.
      (举个例子:py文件中一行代码为print,那么python解释器就会调用自己的打印功能)

    查看进程号:

    import os
    print(os.getpid())    #打印进程id号
    print(os.getppid())     # 父进程id号

    查看进程和杀死进程:

    cmd解释器中:
    tasklist |findstr python  #管道符 过滤 查看python关键字 进程
    干掉python进程
    tskill python
    
    tskill 进程name
    tskill 进程pid号

    运行环境的父进程:

    运行一个xxx.py (python3环境下) , 打印这个进程的父进程id号,发现是pycharm 的id号.为什么呢?
        pycharm 运行 python3 xxx.py , 然后 产生一个 python.exe 进程.所以pycharm是这个python.exe的父进程
        (pycharm 运行 python3 xxx.py     ====>>   python.exe)
    
    PS:如果在cmd中运行,这个python.exe的父进程就是cmd的id号

    jion():

    jion(),主进程等待子进程

    import time
    from multiprocessing import Process
    
    
    def task(name):
        time.sleep(2)
        print('%s' % name)
    
    
    if __name__ == '__main__':
        p = Process(target=task,args=('kitty',))
        p.start()
        p.join()                    #等 子进程运行完毕,主进程才继续往下运行
        print('主进程')

    如果有多个子进程:p1 p2 p3

    p1.start()
    p1.join()
    p2.start()
    p2.join()
    p3.start()
    p3.join()
    # 这种情况下,相当于串行(等待上一个进程执行完,才继续往下执行下一个进程)

    -

    p1.start()
    p2.start()
    p3.start()
    p1.join()
    p2.join()
    p3.join()
    # 这种情况下,是并发(PS:join()的顺序先后没关系)

    可以简洁点:

    p_l = [p1,p2,p3]
    for p in p_l:
        p.start()
    for p in p_l:
        p.join()

    name = None

    进程名可以自定义:

    if __name__ == '__main__':
        p = Process(target=task,args=('kitty',),name='haha')
        p.start()
        p.join()
        print(p.name)           #haha  自定义子进程名字
        print('主进程')

    terminate(): 杀死进程

    is_alive(): 判断进程是否活着

    def task(name):
        time.sleep(2)
        print('%s' % name)
    
    
    if __name__ == '__main__':
        p = Process(target=task,args=('kitty',))
        p.start()
        p.terminate()               #杀死进程p
        print(p.is_alive())         #True  之所以是True,而不是False,是因为杀死进程p.terminate()只是发了一个信号,主进程马上就判断
                                            # (杀死进程需  要时间)
        print('主进程')

    注意:
      慎用, 如果儿子进程开了个孙子进程,就会产生孤儿进程(比较危险)
      现实场景也很少这种操作

    进程池

    1.进程池中存放的就是进程,只不过加上了数目的限制,

    2.进程池造出来后,不会开新的进程,从始至终就是造进程池时定义的数目

    3.等进程池中的所有进程都完毕,先关门,在等(shutdown(wait = True))

    示例:

    import time
    from concurrent.futures import ProcessPoolExecutor
    
    
    def task(name):
        time.sleep(2)
        print('%s' % name)
    
    
    if __name__ == '__main__':
        p = ProcessPoolExecutor(4)          # 立刻造好4个进程
        # p.submit(task,'kitty1')
        # p.submit(task,'kitty2')
        # p.submit(task,'kitty3')
        # p.submit(task,'kitty4')
        for i in range(1, 11):
            p.submit(task, 'kitty%s' % i)       #submit() 往里面丢任务
        print('主进程')

    提交/调用 任务的方式

    1.同步调用:

      提交/调用一个任务,然后就在原地等着,等到该任务执行完毕拿到结果,再执行下一行代码

    2.异步调用:

      提交/调用一个任务,不在原地等着,直接执行下一行代码.

    from concurrent.futures import ProcessPoolExecutor

    新版本中(新模块中)根本就没有同步接口,只有异步接口,就是submit()

    新版本中:

      关门+等

      shutdown(wait = True)

    ---------------------------------------------------------------------------------------


    from multiprocessing import Process, Pool

    老版本中(Pool)中有个同步接口 p.apply()

    老版本中:

      关门+等

      pool.close()

      pool.join()
    --------------------------------------------------------

    同步调用方式:

      开进程 等待 再开,再等这种提交任务的方式,想当于串行

    for p in p_l:
        p.start()
        p.join()

    示例:

    import time
    from concurrent.futures import ProcessPoolExecutor
    
    
    def task(name, n):
        time.sleep(1)
        print('%s' % name)
        return n**2
    
    
    if __name__ == '__main__':
        p = ProcessPoolExecutor(4)
        p_l = []
        for i in range(1, 11):
            obj = p.submit(task, 'kitty%s' % i, i)
            print(obj.result())                 #相当于start和join连用
        print('主进程')
    
    # kitty1
    # 1
    # kitty2
    # 4
    # kitty3
    # 9
    # kitty4
    # 16
    # kitty5
    # 25
    # kitty6
    # 36
    # kitty7
    # 49
    # kitty8
    # 64
    # kitty9
    # 81
    # kitty10
    # 100
    # 主进程

    异步调用方式:

    for i in range(10):
        p.submit(func,'xx')

    示例:

    import time
    from concurrent.futures import ProcessPoolExecutor
    
    
    def task(name, n):
        time.sleep(1)
        print('%s' % name)
        return n**2
    
    
    if __name__ == '__main__':
        p = ProcessPoolExecutor(4)
        p_l = []
        for i in range(1, 11):
            obj = p.submit(task, 'kitty%s' % i, i)      # obj是个对象,通过对象拿到结果
            p_l.append(obj)
        p.shutdown(wait = True)            #shutdown(wait = True) 等,但是前提是进程池中不能再放进新的任务了,否则数目不准确(先关门+等)
        print('主进程')
        for i in p_l:
            print(i.result())
    
    # kitty1
    # kitty2
    # kitty3
    # kitty4
    # kitty5
    # kitty6
    # kitty7
    # kitty8
    # kitty9
    # kitty10
    # 主进程
    # 1
    # 4
    # 9
    # 16
    # 25
    # 36
    # 49
    # 64
    # 81
    # 100
  • 相关阅读:
    SVG前戏—让你的View多姿多彩
    分享几个Android很强势的的开源框架
    终于,我还是下决心学Java后台了
    金9银10,分享几个重要的Android面试题
    django-多表操作2
    python基础-文件操作
    django-单表操作
    django-多表操作
    django-模板层基础2
    djano-模板层基础知识
  • 原文地址:https://www.cnblogs.com/zhzhlong/p/9297141.html
Copyright © 2011-2022 走看看