美文网首页
python 的进程、线程以及协程(1)

python 的进程、线程以及协程(1)

作者: nice生活 | 来源:发表于2017-10-26 22:03 被阅读0次

    python 的进程、线程以及协程(1)

    python实现多进程主要有两种,一种是os模块的fork方法,另一种是multiprocessing,他们的区别在于第一种仅适用Unix/linux,对win不支持,后者是跨平台的.

    multiprocessing模块创建多进程:

    通过实现Process类来创建:Process(group=None,target=None,nam=None,args=(),kwargs={})
    

    参数说明:
    target:表示这个进程实例所调用对象

    args:表示调用对象的位置参数元组;

    kwargs:表示调用对象的关键字参数字典;

    name:为当前进程实例的别名;

    group:大多数情况下用不到;
    Process类常用方法:

    is_alive():判断进程实例是否还在执行;

    join([timeout]):是否等待进程实例执行结束,或等待多少秒;

    start():启动进程实例(创建子进程);

    run():如果没有给定target参数,对这个对象调用start()方法时,就将执行对象中的run()方法;

    terminate():不管任务是否完成,立即终止;

    实例

    代码块

    from multiprocessing import Process
    
    import os
    
    def run(name,height=0,weight=0):
    
        print("process %s:%s,height:%s,weight:%s"% (name, os.getpid(), height, weight))
    
    if__name__  == '__main__':
    
        for i in range(8):
    
            p = Process(target=run, args=(str(i),), kwargs={'height':100,'weight':50})
    
            print('process will start')
    
            p.start()
    
    p.join()# 实现进程的同步,等待最后子进程结束,如果不加的这个语句可能会出现主进程结束而子进程没有结束,因为主进程结束导致未完成的主进程结束
    
    print('process end')
    

    进程池pool:

    multiprcessing 提供了 Pool类来代表进程池对象,Pool 可以提供指定的进程提供用户调用,默认是cpu的核数。但有新的请求提交到pool时 如果池没有满,就创建,如果满了,就会等待,直到有进程结束,才会创建新的进程来处理.

    Pool(processes=None,initializer=None,initargs(),maxtasksperchild=None,context=None)
    参数说明:
    processes:进程池最大个数,如果是None,通过返回的数字os.cpu_count()被使用(默认是cpu的核数)

    initializer:如果不是None,那么将在将启动每个工作进程时调用initializer( initargs)。*

    maxtasksperchild:一个工作进程在它退出之前完成的任务的数量,被一个新的工作 进程所取代,从而使未使用的资源得到释放,默认的maxtasksperchild是None,这意味着工作进程将与池一样长
    (允许在池内的工作进程在退出前只完成一定数量的工作,然后进行清理,并生成新的进程来替换旧的工作)

    context:可以用来指定启动工作进程所用的上下文。通常,池是使用函数multiprocess. pool()或上下文对象的pool()方法创建的。在这两种情况下都适当地设置了上下文。

    常用方法:

    apply(func[, args=()[, kwds={}]]):
    往进程池添加任务进程.不太常用用,使用apply()进程会被阻塞直到函数执行结束

    apply_async(func[,args[,kwds[,callback[,error_callback]]]]):
    apply_async()是apply()函数的变体,如果指定callback,callback应该是一个可以接受单个参数的函数接收func返回值,在调用失败,在这种情况下,将使用error_callback,如果指定error_callback,error_callback应该是一个可以接受单个参数的函数,如果目标函数调用失败,则会使用异常实例调用error_callback ( callback应该立即完成,否则处理结果的线程将被阻塞。)

    map(func,iterable[,chunksize]):
    一个类似于map()内置函数的等价函数(它只支持一个可迭代的参数)。它会使进程阻塞与此直到结果返回 ,返回列表,该方法将迭代分成若干块,并将其提交到进程池作为单独的任务。这些块的(大约)大小可以通过将chunksize设置为一个正整数来指定。

    map_async(func, iterable[, chunksize[, callback]])
    与map用法一致,但是它是非阻塞的。可以同过返回结果.get()得到进程池返回结果列表

    close()
    关闭进程池(pool),使其不在接受新的任务。

    terminate()
    结束工作进程,不在处理未处理的任务。

    join()
    主进程阻塞等待子进程的退出,join方法必须在close或terminate之后使用。

    实例代码

    
    from multiprocessing import Pool
    import os,time,random
    
    
    def run(name):
    
        print('prcess%s(%s)'% (name,os.getpid()))
    
        time.sleep(random.random()*3)
        print('end %s'% name)
        return name
    
    
    def run1():
        print(1);
    
    
    if __name__ == '__main__':
        args = (10, 20, 30)
        List = [1,2,3,4,5,6,7,8,9,10,11]
        p = Pool(processes=4,initializer=run1,)
        result = p.map_async(run,List)
        p.close()
        p.join()
        print('-'*80)
    
    

    结果


    这里写图片描述
    from multiprocessing import Pool
    import os,time,random
    
    
    def run(name):
    
        print('prcess%s(%s)'% (name,os.getpid()))
    
        time.sleep(random.random()*3)
        print('end %s'% name)
        return name
    
    
    def run1():
        print(1);
    
    
    if __name__ == '__main__':
        args = (10, 20, 30)
        List = [1,2,3,4,5,6,7,8,9,10,11]
        p = Pool(processes=4,initializer=run1,maxtasksperchild=2)
        result = p.map_async(run,List)
        p.close()
        p.join()
        print('-'*80)
    
    这里写图片描述

    上面的两个结果可以看出每个进程启动前会调用initializer函数,当我设置maxtasksperchild=2的时候可以看出每个进程完成2次任务会被新的进程替代

    相关文章

      网友评论

          本文标题:python 的进程、线程以及协程(1)

          本文链接:https://www.haomeiwen.com/subject/pfjlpxtx.html