zoukankan      html  css  js  c++  java
  • Python多进程编程

    Process

    创建进程的类:Process([group [, target [, name [, args [, kwargs]]]]]),target表示调用对象,args表示调用对象的位置参数元组。kwargs表示调用对象的字典。name为别名。group实质上不使用。


    方法:is_alive()、join([timeout])、run()、start()、terminate()。其中,Process以start()启动某个进程。

    属性:authkey、daemon(要通过start()设置)、exitcode(进程在运行时为None、如果为–N,表示被信号N结束)、name、pid。其中daemon是父进程终止后自动终止,且自己不能产生新进程,必须在start()之前设置。

    例1.1:创建函数并将其作为单个进程

    import multiprocessing
    import time
    
    def worker(interval):
        n = 5
        while n > 0:
            print("The time is {0}".format(time.ctime()))
            time.sleep(interval)
            n -= 1
    
    if __name__ == "__main__":
        p = multiprocessing.Process(target = worker, args = (1,)) #target表示调用对象,args传入调用对象的参数元组#
        p.start()
        print ("p.pid:", p.pid)
        print ("p.name:", p.name)
        print ("p.is_alive:", p.is_alive())

    结果:

    p.pid: 8736
    p.name: Process-1
    p.is_alive: True
    The time is Tue Apr 21 20:55:12 2015
    The time is Tue Apr 21 20:55:15 2015
    The time is Tue Apr 21 20:55:18 2015
    The time is Tue Apr 21 20:55:21 2015
    The time is Tue Apr 21 20:55:24 2015

    例1.2:创建函数并将其作为多个进程

    import multiprocessing
    import time
    
    def worker_1(interval):
        print ("worker_1")
        time.sleep(interval)
        print ("end worker_1")
    
    def worker_2(interval):
        print ("worker_2")
        time.sleep(interval)
        print ("end worker_2")
    
    def worker_3(interval):
        print ("worker_3")
        time.sleep(interval)
        print ("end worker_3")
    
    if __name__ == "__main__":
        p1 = multiprocessing.Process(target = worker_1, args = (2,))
        p2 = multiprocessing.Process(target = worker_2, args = (3,))
        p3 = multiprocessing.Process(target = worker_3, args = (4,))
    
        p1.start()
        p2.start()
        p3.start()
    
        print("The number of CPU is:" + str(multiprocessing.cpu_count()))
        for p in multiprocessing.active_children():
            print("child   p.name:" + p.name + "	p.id" + str(p.pid))
        print ("END!!!!!!!!!!!!!!!!!")

    结果:

    The number of CPU is:4
    child   p.name:Process-3    p.id7992
    child   p.name:Process-2    p.id4204
    child   p.name:Process-1    p.id6380
    END!!!!!!!!!!!!!!!!!
    worker_1
    worker_3
    worker_2
    end worker_1
    end worker_2
    end worker_3

    例1.3:将进程定义为类

    import multiprocessing
    import time
    
    class ClockProcess(multiprocessing.Process):
        def __init__(self, interval):
            multiprocessing.Process.__init__(self)
            self.interval = interval
    
        def run(self):
            n = 5
            while n > 0:
                print("the time is {0}".format(time.ctime()))
                time.sleep(self.interval)
                n -= 1
    
    if __name__ == '__main__':
        p = ClockProcess(3)
        p.start()      

    :进程p调用start()时,自动调用run()

    结果

    the time is Tue Apr 21 20:31:30 2015
    the time is Tue Apr 21 20:31:33 2015
    the time is Tue Apr 21 20:31:36 2015
    the time is Tue Apr 21 20:31:39 2015
    the time is Tue Apr 21 20:31:42 2015

    Pool

    在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,此时可以发挥进程池的功效。
    Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。

    例1:使用进程池(非阻塞)

    #coding: utf-8
    import multiprocessing
    import time
    
    def func(msg):
        print ("msg:", msg)
        time.sleep(1)
        print ("end")
    
    if __name__ == "__main__":
        pool = multiprocessing.Pool(processes = 3)
        for i in range(4):
            msg = "hello %d" %(i)
            pool.apply_async(func, (msg, ))   #传递参数,保持执行的进程总数为processes(此处设定为3),当一个进程执行完毕后再添加新的进程进去
    
        print ("Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~")
        pool.close()
        pool.join()   #调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
        print ("Sub-process(es) done.")

    执行结果

    mMsg: hark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~ello 0
     
    msg: hello 1
    msg: hello 2
    end
    msg: hello 3
    end
    end
    end
    Sub-process(es) done.

    函数解释:

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

    执行说明:创建一个进程池pool,并设定进程的数量为3,xrange(4)会相继产生四个对象[0, 1, 2, 4],四个对象被提交到pool中,因pool指定进程数为3,所以0、1、2会直接送到进程中执行,当其中一个执行完事后才空出一个进程处理对象3,所以会出现输出“msg: hello 3”出现在"end"后。因为为非阻塞,主函数会自己执行自个的,不搭理进程的执行,所以运行完for循环后直接输出“mMsg: hark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~”,主程序在pool.join()处等待各个进程的结束。

    例2:使用进程池(阻塞)

    #coding: utf-8
    import multiprocessing
    import time
    
    def func(msg):
        print ("msg:", msg)
        time.sleep(1)
        print ("end")
    
    if __name__ == "__main__":
        pool = multiprocessing.Pool(processes = 3)
        for i in range(4):
            msg = "hello %d" %(i)
            pool.apply(func, (msg, ))   #传递参数,保持执行的进程总数为processes(此处设为3),当一个进程执行完毕后再添加新的进程进去
    
        print ("Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~")
        pool.close()
        pool.join()   #调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
        print ("Sub-process(es) done.")

    执行结果:

    msg: hello 0
    end
    msg: hello 1
    end
    msg: hello 2
    end
    msg: hello 3
    end
    Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~
    Sub-process(es) done.
  • 相关阅读:
    Linux下的内核测试工具——perf使用简介
    浅谈C++中指针和引用的区别
    成为Java顶尖程序员 ,看这11本书就够了
    spring注解详解
    Spring AOP详解和实现方式
    Spring IoC中各个注解的理解和使用
    NameNode配置HA后及其反过程Hive路径不正确的问题解决
    [maven] 常用插件解析
    Saiku3.15去除License与主界面
    saiku系列文章
  • 原文地址:https://www.cnblogs.com/singeldiego/p/5256610.html
Copyright © 2011-2022 走看看