• Python中的多进程:fork和multiprocessing


    Python的多进程

    套路1:os.fork()

    先敲段代码:

    #!/usr/bin/env python3
    
    import os
    
    os.fork()
    print('1111111111')
    
    

    执行结果

    1111111111
    1111111111
    
    • fork函数一旦运行就会生出一条新的进程,2个进程一起执行导致输出了2行。

    再敲段代码

    #!/usr/bin/env python3
    
    import os
    import time
    
    res = os.fork()
    print('res == %d'%res)
    if res == 0:
        print('我是子进程,我的pid是:%d,我的父进程id是:%d'%(os.getpid(),os.getppid()))
    else:
        print('我是父进程,我的pid是:%d'%os.getpid())
    
    

    执行结果

    res == 105297
    我是父进程,我的pid是:105296
    res == 0
    我是子进程,我的pid是:105297,我的父进程id是:105296
    
    
    • fork()运行时,会有2个返回值,返回值为大于0时,此进程为父进程,且返回的数字为子进程的PID;当返回值为0时,此进程为子进程。
    • 注意:父进程结束时,子进程并不会随父进程立刻结束。同样,父进程不会等待子进程执行完。
    • 注意:os.fork()无法在windows上运行。

    套路2:multiprocessing.Process

    先敲段代码,来创建一个进程

    
    #!/usr/bin/env python3
    
    from multiprocessing import Process
    import time
    
    def A():
        while True:
            print('正在调用函数')
            time.sleep(1)
    
    p = Process(target = A) #创建进程对象,并指定进程将来要执行的函数.
    p.start()  #启动进程.
    
    

    执行结果

    正在调用函数
    正在调用函数
    正在调用函数
    ......
    

    再敲段代码,实现多进程同步执行

    
    #!/usr/bin/env python3
    import time
    from multiprocessing import Process
    
    def A(num):
        while True:
            print('正在调用函数%d'%num)
            time.sleep(1)
    
    for i in range(2):
        p = Process(target = A, args = (i,)) #创建进程对象,并指定进程将来要执行的函数.
        p.start()  #启动进程.
        
        exit()
        
    

    执行结果

    正在调用函数1
    正在调用函数2
    正在调用函数1
    正在调用函数2
    ...
    
    • 注意,Process创建的进程必须执行完,主程序才会结束,用exit()也不能强退。

    套路3:multiprocessing.Process的run()方法

    上代码

    
    #!/usr/bin/env python3
    
    import os
    import time
    from multiprocessing import Process
    
    class NewProcess(Process): #继承Process类创建一个新类
        def __init__(self,num):
            self.num = num
            super().__init__()
    
        def run(self):  #重写Process类中的run方法.
            while True:
                print('我是进程%d,我的pid是:%d'%(self.num,os.getpid()))
                time.sleep(1)
    
    for i in range(2):
        p = NewProcess(i)
        p.start()
    
    

    执行结果

    我是进程0,我的pid是:105653
    我是进程1,我的pid是:105654
    我是进程0,我的pid是:105653
    我是进程1,我的pid是:105654
    我是进程0,我的pid是:105653
    我是进程1,我的pid是:105654
    ...
    
    
    • 当不给Process指定target时,会默认调用Process类里的run()方法。这和指定target效果是一样的,只是将函数封装进类之后便于理解和调用。

    套路4:multiprocessing.Pool 进程池

    
    #!/usr/bin/env python3
    
    import time
    from multiprocessing import Pool
    
    def A():
        for i in range(5):
            print(i)
            time.sleep(1)
    
    pool = Pool(2) #定义进程池大小
    for i in range(5):
        pool.apply_async(A) #使用非阻塞方式调用func,阻塞是apply()
    
    pool.close() #关闭Pool,使其不再接受新的任务
    pool.join() #主进程阻塞,等待子进程的退出
    
    
    • 对Pool对象调用join()方法会等待所有子进程执行完毕。调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。
    • Pool.terminate():一旦运行到此步,不管任务是否完成,立即终止。

  • 相关阅读:
    奇怪的html控件textarea
    ado.net快速上手实践篇(二)
    巧用apply让javascript函数仅执行一次
    javascript:像操作Array一样操作NodeList
    javascript下的数值型比较真的没有那么简单
    ado.net快速上手实践篇(一)
    ado.net快速上手疑问及解答(完结篇)
    如何利用【百度地图API】进行定位?非GPS定位
    【百度地图API】关于如何进行城市切换的三种方式
    【百度地图API】建立全国银行位置查询系统(四)——如何利用百度地图的数据生成自己的标注
  • 原文地址:https://www.cnblogs.com/PrettyTom/p/6582357.html
Copyright © 2020-2023  润新知