• Python 进程、进程池


    Python 进程

    1、创建进程

    # 创建进程
    
    from multiprocessing import Process
    
    def foo(i):
        print('say hi', i)
    
    if __name__ == '__main__':
        for i in range(3):
            p = Process(target=foo, args=(i, ))
            p.start()
        print('main proccess stop')
        
    -----------输出结果-----------
        main proccess stop
        say hi 0
        say hi 2
        say hi 1

     注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。

    2、进程数据共享

    进程各自持有一份数据,默认无法共享数据

    # 进程数据共享(默认不共享)
    
    from multiprocessing import Process, Array
    from multiprocessing import Manager
    import time
    li = []
    
    def foo(i):
        li.append(i)
        print(li)
        print('say hi', i)
    
    if __name__ == '__main__':
        for i in range(3):
            p = Process(target=foo, args=(i, ))
            p.start()
        print('main proccess stop')
        
    ----------输出结果-----------
        main proccess stop
        [1]
        say hi 1
        [0]
        say hi 0
        [2]
        say hi 2

    1)、通过Array 实现进程间数据共享

    # 通过Array实现进程数据共享
    
    from multiprocessing import Process, Array
    import time
    temp = Array('i', [11, 22, 33, 44, 55])
    
    def foo(i):
        temp[i] = 100 + i
        for item in temp:
            print('第%s个进程' % i, '--------->', item)
    
    
    if __name__ == '__main__':
        for i in range(1, 4, 1):
            p = Process(target=foo, args=(i, ))
            p.start()
        print('main proccess stop')
    输出结果
    ----------输出结果------------
        main proccess stop
        第1个进程 ---------> 11
        第1个进程 ---------> 101
        第1个进程 ---------> 33
        第1个进程 ---------> 44
        第1个进程 ---------> 55
        第2个进程 ---------> 11
        第2个进程 ---------> 22
        第2个进程 ---------> 102
        第2个进程 ---------> 44
        第2个进程 ---------> 55
        第3个进程 ---------> 11
        第3个进程 ---------> 22
        第3个进程 ---------> 33
        第3个进程 ---------> 103
        第3个进程 ---------> 55
    输出结果
    2)、通过manage.dict()实现进程间数据共享
    from multiprocessing import Process, Manager
    import time
    
    mangers = Manager()
    dic = mangers.dict()
    
    def foo(i):
        time.sleep(1)
        dic[i] = 100 + 1
        print(dic.values())
    
    for i in range(10):
        p = Process(target=foo, args=(i, ))
        p.start()
        p.join()
    
    print('main proccess stop')
    -------------输出结果-----------------
    [101]
    [101, 101]
    [101, 101, 101]
    [101, 101, 101, 101]
    [101, 101, 101, 101, 101]
    [101, 101, 101, 101, 101, 101]
    [101, 101, 101, 101, 101, 101, 101]
    [101, 101, 101, 101, 101, 101, 101, 101]
    [101, 101, 101, 101, 101, 101, 101, 101, 101]
    [101, 101, 101, 101, 101, 101, 101, 101, 101, 101]
    main proccess stop
    输出结果
      'c': ctypes.c_char,  'u': ctypes.c_wchar,
        'b': ctypes.c_byte,  'B': ctypes.c_ubyte,
        'h': ctypes.c_short, 'H': ctypes.c_ushort,
        'i': ctypes.c_int,   'I': ctypes.c_uint,
        'l': ctypes.c_long,  'L': ctypes.c_ulong,
        'f': ctypes.c_float, 'd': ctypes.c_double
    类型对应表

     3)、通过queues.Queue()实现进程间数据共享

    # Queues 数据共享
    
    from multiprocessing import Process, queues
    import multiprocessing
    
    def f(i, q):
        print(i, q.get())
    
    if __name__ == '__main__':
        q = queues.Queue(ctx=multiprocessing)
    
        q.put('h1')
        q.put('h2')
        q.put('h3')
    
        for i in range(3):
            p = Process(target=f, args=(i, q, ))
            p.start()
    ---------输出结果----------
        2 h1
        1 h2
        0 h3
    输出结果
    当创建进程时(非使用时),共享数据会被拿到子进程中,当进程中执行完毕后,再赋值给原值。
    from multiprocessing import Process, Array, RLock
    
    def Foo(lock,temp,i):
        """
        将第0个数加100
        """
        lock.acquire()
        temp[0] = 100 + i
        for item in temp:
            print(i,'----->',item)
        lock.release()
    
    lock = RLock()
    temp = Array('i', [11, 22, 33, 44])
    if __name__ == '__main__':
        for i in range(10):
            p = Process(target=Foo,args=(lock,temp,i,))
            p.start()
    1 -----> 101
    1 -----> 22
    1 -----> 33
    1 -----> 44
    0 -----> 100
    0 -----> 22
    0 -----> 33
    0 -----> 44
    2 -----> 102
    2 -----> 22
    2 -----> 33
    2 -----> 44
    3 -----> 103
    3 -----> 22
    3 -----> 33
    3 -----> 44
    4 -----> 104
    4 -----> 22
    4 -----> 33
    4 -----> 44
    5 -----> 105
    5 -----> 22
    5 -----> 33
    5 -----> 44
    9 -----> 109
    9 -----> 22
    9 -----> 33
    9 -----> 44
    7 -----> 107
    7 -----> 22
    7 -----> 33
    7 -----> 44
    8 -----> 108
    8 -----> 22
    8 -----> 33
    8 -----> 44
    6 -----> 106
    6 -----> 22
    6 -----> 33
    6 -----> 44
    输出结果

     3、进程池

    进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

    # 进程池
    
    from multiprocessing import Pool
    from time import sleep
    
    def f(x):
        for i in range(3):
            print('%s---------->%s' % (i, x))
            sleep(1)
    
    def main():
        # 创建进程池,进程池最多有三个可用进程
        pool = Pool(processes=3)
        for i in range(11, 20):
            result = pool.apply_async(f, (i,))
        pool.close()
        pool.join()
        if result.successful():
            print('successful')
    
    if __name__ == '__main__':
        main()
    
    '''
    先创建容量为3的进程池,
    然后将f(i)依次传递给它,运行脚本后利用ps aux | grep pool.py查看进程情况,会发现最多只会有三个进程执行。
    pool.apply_async()  用来向进程池提交目标请求,
    pool.join()         是用来等待进程池中的worker进程执行完毕,防止主进程在worker进程结束前结束。但必pool.join()必须使用在pool.close()或者pool.terminate()之后。
    close()跟terminate()的区别
        close()会等待池中的worker进程执行结束再关闭pool,
        terminate()则是直接关闭。
    result.successful()表示整个调用执行的状态,如果还有worker没有执行完,则会抛出AssertionError异常。
    
    '''

    函数解释:
    •apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞的
    •close()    关闭pool,使其不在接受新的任务。
    •terminate()    结束工作进程,不在处理未完成的任务。
    •join()    主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。

    # 阻塞进程池
    
    from multiprocessing import Pool
    import time
    def func(msg):
        for i in range(3):
            print('msg:', msg)
            time.sleep(1)
            print('end')
    
    def main():
        pool = Pool(processes=3)
        for i in range(4):
            msg = 'hello %s' % i
            # 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
            result = pool.apply(func, (msg,))
        pool.close()
        pool.join()
        # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
    
        print('successful')
    
    if __name__ == '__main__':
        main()
  • 相关阅读:
    [PTA练习] 愿天下有情人都是失散多年的兄妹(25分)
    sql server远程连接非1433端口
    java把double转化为long型
    StringUtils工具类
    JfreeChart折线图
    Log4j配置
    Ibatis,Spring整合(注解方式注入)
    Spring中的autowire属性(转)
    MyBatis3入门样例
    struts2 ibatis Spring系统架构图
  • 原文地址:https://www.cnblogs.com/yxy-linux/p/5685748.html
Copyright © 2020-2023  润新知