zoukankan      html  css  js  c++  java
  • Process类,Thread类,Pool类,gevent类,ProcessPoolExecutor,ThreadPoolExecutor的用法比较

    一 Process类

      multiprocessing模块下的一个类

      创建子进程。

      有两种方法

      方法一

    复制代码
    from multiprocessing import Process
    import os
    def foo():
        print('%s from foo'%os.getpid())
    def bar():
        print('%s from bar' % os.getpid())
    if __name__ == '__main__':
        p1=Process(target=foo)
        p2=Process(target=bar)
        p1.start()
        p2.start()
        p1.join()
        p2.join()
        print('%s over'%os.getpid())
    复制代码

      输出: 

    13524 from foo
    12848 from bar
    12696 over

      方法二

    复制代码
    from multiprocessing import Process
    import os
    class Myprocess(Process):
        def __init__(self,name):
            super().__init__()
            self.name=name
        def run(self):
            print('%s from %s' % (os.getpid(),self.name))
    if __name__ == '__main__':
        p1=Myprocess('foo')
        p2=Myprocess('bar')
        p1.start()
        p2.start()
        p1.join()
        p2.join()
        print('%s over' % os.getpid())
    复制代码

      输出:

    15260 from foo
    5980 from bar
    8844 over

    二 Thread类

      threading模块下的类

      创建线程

      有两种方法

      与Process类一样。

    三 Pool类

      Pool类的方法:

        p=Pool()

        p.apply_async(),异步提交任务,生成ApplyResult对象

        p.close() 

        p.join()

        ApplyResult.get(),从ApplyResult对象中获取返回值。

    复制代码
    from multiprocessing import Pool
    import os,time
    def foo():
        time.sleep(1)
        print('%s from foo'%os.getpid())
        return 'foo'
    def bar():
        time.sleep(2)
        print('%s from bar' % os.getpid())
        return 'bar'
    if __name__ == '__main__':
        p=Pool()
        t1=time.time()
        res1=p.apply_async(foo)
        res2=p.apply_async(bar)
        p.close()
        p.join()
        print(res1)
        print(time.time()-t1)          ##多出来的0.15秒是开启进程所花费的时间
        t2=time.clock()
        print(res1.get())
        print(res2.get())
        print(time.clock()-t2)
    复制代码

      输出:

    复制代码
    12468 from foo
    8832 from bar
    <multiprocessing.pool.ApplyResult object at 0x00000126511CEE48>
    2.1609864234924316
    foo
    bar
    2.1880321932470032e-05
    复制代码

      map()方,比较常用。

      官方介绍:

    Apply `func` to each element in `iterable`, collecting the results
            in a list that is returned.

      废话少说,上代码

    复制代码
    import time
    from multiprocessing import Pool
    
    def foo(x):
        time.sleep(1)
        return x*x
    
    if __name__ == '__main__':
        l = [1,2,3,4,5,6,7,8,9,10]
        t1 = time.time()
        p = Pool()
        print(time.time()-t1)
        res = p.map(foo,l) # 这行代码表示所有的进行都已经执行完了,并且每个进程的结果都拿到,放在了res中
        print(time.time()-t1)   
        print(res,type(res))
        p.close()
        p.join()
        print(time.time()-t1)
    复制代码

      输出:

    0.14187192916870117
    2.2597498893737793
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] <class 'list'>
    2.401075601577759

    四 gevent

      gevent是一个基于协程的Python网络库。

      单线程实现并发,协程。

      需要用到猴子补丁。

      方法:

        g1=gevent.spawn(func):提交任务,生成Greenlet对象--g1。

        g1.join(),阻塞,直到g1任务完成。

        g1.value。从Greenlet对象g1中获取返回值。   

    复制代码
    import gevent
    from gevent import monkey;monkey.patch_all()
    import os,time
    from threading import current_thread
    def foo():
        time.sleep(1)
        print('%s  %s from foo'%(os.getpid(),current_thread().getName()))
    def bar():
        time.sleep(2)
        print('%s  %s from bar' % (os.getpid(),current_thread().getName()))
    t1=time.time()
    g1=gevent.spawn(foo)
    g2=gevent.spawn(bar)
    print(g1,g2)
    g1.join()
    g2.join()
    print(time.time()-t1)
    复制代码

      输出:

    <Greenlet at 0x1e3fc1396d0: foo> <Greenlet at 0x1e3fc139800: bar>
    7536  DummyThread-1 from foo
    7536  DummyThread-2 from bar
    2.0017032623291016              #可以看到协程开启进程花销非常小。

    五 ProcessPoolExecutor

      创建多进程

      concurrent.futures库内的ProcessPoolExecutor类

      executor=ProcessPoolExecutor():生成一个ProcessPoolExecutor对象;

      future=executor.submit():提交任务,返回一个Future对象。

      executor.shutdown()。相当于Pool类中的close()和join()

      future.result():从Future对象中获取其返回值。

    复制代码
    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    import os,time
    from threading import current_thread
    def foo():
        time.sleep(1)
        print('%s  %s from foo'%(os.getpid(),current_thread().getName()))
        return 'foo'
    def bar():
        time.sleep(2)
        print('%s  %s from bar' % (os.getpid(),current_thread().getName()))
        return 'bar'
    if __name__ == '__main__':
        t1=time.time()
        executor=ProcessPoolExecutor()
        print('executor',executor)
        future1=executor.submit(foo)
        future2=executor.submit(bar)
        print(future1,future2)
        executor.shutdown()
        print(future1.result())
        print(future2.result())
        print(time.time()-t1)
    复制代码

      输出:

    6480  MainThread from foo
    6756  MainThread from bar
    foo
    bar
    2.7526917457580566                   #可以看到创建进程还是比较花费时间的

    六 ThreadPoolExecutor()

      创建多线程

      concurrent.futures库内的ProcessPoolExecutor类

      executor=ThreadPoolExecutor():生成一个ThreadPoolExecutor对象;

      future=executor.submit():提交任务,返回一个Future对象。

      executor.shutdown()。相当于Pool类中的close()和join()。

      future.result():从Future对象中获取其返回值。

      

    复制代码
    from concurrent.futures import ThreadPoolExecutor
    import os,time
    from threading import current_thread
    def foo():
        time.sleep(1)
        print('%s  %s from foo'%(os.getpid(),current_thread().getName()))
        return 'foo'
    def bar():
        time.sleep(2)
        print('%s  %s from bar' % (os.getpid(),current_thread().getName()))
        return 'bar'
    if __name__ == '__main__':
        t1=time.time()
        executor=ThreadPoolExecutor()
        print('executor',executor)
        future1=executor.submit(foo)
        future2=executor.submit(bar)
        print(future1,future2)
        executor.shutdown()
        print(future1.result())
        print(future2.result())
        print(time.time()-t1)
    复制代码

      输出:

    复制代码
    executor <concurrent.futures.thread.ThreadPoolExecutor object at 0x0000020073EAAAC8>
    <Future at 0x20073eb4198 state=running> <Future at 0x20074176940 state=running>
    4380  <concurrent.futures.thread.ThreadPoolExecutor object at 0x0000020073EAAAC8>_0 from foo         #可以看到进程号是一样的
    4380  <concurrent.futures.thread.ThreadPoolExecutor object at 0x0000020073EAAAC8>_1 from bar
    foo
    bar
    2.001234531402588                     #相比较开启进程,线程开启的时间非常快,花销非常小
    复制代码
  • 相关阅读:
    VMWare的The network bridge on device VMnet0 is not running故障解决
    函数索引 ORA30553: The function is not deterministic 解决方法
    Oracle 9i EXP XDB.DBMS_XDBUTIL_INT must be declared
    Event 10053 执行计划 绑定变量 Bind peeking
    Oracle Data Guard 理论知识
    Oracle 9i ORA04062 timestamp of package SYS DBMS_SNAPSHOT_UTL has been changed ORA06512 at SYS DBMS_SNAPSHOT
    Oracle Data Guard Linux 平台 Logical Standby 创建实例
    Oracle RAC 归档 与 非归档 切换
    Oracle 9i EXP XDB.DBMS_XDBUTIL_INT must be declared
    ORA16014: log string sequence# string not archived, no available destinations Flash Recovery Area 空间不足
  • 原文地址:https://www.cnblogs.com/ExMan/p/10138866.html
Copyright © 2011-2022 走看看