• python——多进程


    python 其实是单线程程序,之所以有多线程是因为它是利用上下分时的功能让人感觉看起来是多线程。

    python 多线程不适合cpu密集操作性的任务,适合io操作密集的任务。

    多并发效果:

    import multiprocessing  
    import time
    def f(name):    
        print('hello', name)
     
    if __name__ == '__main__':  #注意这里的name==main,不是name==name
        for i in range(10):    
            p = multiprocessing.Process(target=f, args=(i,)) #定义多进程对象
            p.start()


    import multiprocessing也可以写成from multiprocessing import Process,但是下面使用的时候,就可以直接使用Process方法了。

    import time,threading
    import multiprocessing
    
    def thread_run():
        print threading.get_ident()   #得到线程号
    def run1(name):
        time.sleep(1)
        print 'hello',name
        t=threading.Thread(target=thread_run,)  #定义线程对象
        t.start()
    if __name__ == '__main__':  
        for i in range(10):
            p = multiprocessing.Process(target = run1 ,args=(i,))  #定义进程对象
            p.start()
    

    进程间通讯

    Queues:这里的Queues跟线程中的queue不是一样的,这里指的是from multiprocessing import  Queue进程中的Queue

    #coding:utf-8
    from multiprocessing import Queue,Process
    def run2(qq):
        qq.put('123')
    if __name__=='__main__':
        q=Queue()
        p=Process(target=run2,args=(q,))
        p.start()
        print q.get()
    

    Pipes(管道)

    跟socket的send、recv一样可以发送接收信息

    from multiprocessing import Process, Pipe
    def f(conn):
        conn.send([42, None, 'hello from child'])
        conn.send([42, None, 'hello from child2'])#双方可以互换的发送和接受信息。
        print("from parent:",conn.recv())
        conn.close()
    if __name__ == '__main__':
        parent_conn, child_conn = Pipe()
        p = Process(target=f, args=(child_conn,))
        p.start()
        print(parent_conn.recv())  # prints "[42, None, 'hello']"
        print(parent_conn.recv())  # prints "[42, None, 'hello']"
        parent_conn.send("小王可好")
        p.join() #等待p进程的结束
    

    Managers

      Managersk可以实现列表,字典,命名空间,锁,rlock,semaphore,boundedsemaphore,condition,事件队列,势垒,和阵列数据的共享和修改。

    #coding:utf-8
    from multiprocessing import Process, Manager
    import os,time
     
    def f(d, l):
        d[1] = '1'
        d['2'] = 2
        d[0.25] = None
        l.append(os.getpid()) #将当期进程id添加到列表中
        print(l)
        time.sleep(2) 
    if __name__ == '__main__':
        with Manager() as manager:
            d = manager.dict()  #可在多个进程中共享数据的字典 
            l = manager.list(range(5))  #可在多个进程中共享5个数据的列表
            p_list = []
            for i in range(10):
                p = Process(target=f, args=(d, l))
                p.start()
                p_list.append(p)
            for res in p_list:
                res.join()  # 等待所有子进程执行完 
            print(d) #打印字典d
            print(l)   #打印列表l
    

    进程同步

    #coding:utf-8
    from multiprocessing import Process, Lock
     
    def f(l, i):
        l.acquire()  #加锁
        try:
            print('hello world', i)
        finally:
            l.release()  #释放锁
            print i
     
    if __name__ == '__main__':
        lock = Lock()
     
        for num in range(10):
            Process(target=f, args=(lock, num)).start()
    

    进程池  

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

    进程池中有两个方法:

    • apply  进程串行
    • apply_async   进程并行
    from  multiprocessing import Process,Pool
    import time,os
     
    def Foo(i):
        time.sleep(2)
        print 'foo is', os.getpid()
        return i+100 
    def Bar(arg):
        print('-->exec done:',os.getpid())
    if __name__=='__main__': #windows 必须加
        pool = Pool(3) #运行进程池同时放进3个数据      
        for i in range(10):
            pool.apply_async(func=Foo, args=(i,),callback=Bar) #callback回调,执行完foo,再调用Bar
            #pool.apply(func=Foo, args=(i,))    
        print('end',os.getpid())
        pool.close()
        pool.join()#进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
    

    结果:

    ('end', 22868)
    foo is 10768
    ('-->exec done:', 22868)
    foo is 22060
    ('-->exec done:', 22868)
    foo is 23728
    ('-->exec done:', 22868)
    foo is 10768
    ('-->exec done:', 22868)
    foo is 22060
    ('-->exec done:', 22868)
    foo is 23728
    ('-->exec done:', 22868)
    foo is 10768
    ('-->exec done:', 22868)
    foo is 22060
    ('-->exec done:', 22868)
    foo is 23728
    ('-->exec done:', 22868)
    foo is 10768
    ('-->exec done:', 22868)

  • 相关阅读:
    移动硬盘插入电脑后检测到却不显示如何解决?
    Js求角度、三角形、弧度计算
    Python之常用模块(一)
    PostgreSQL中的MVCC 事务隔离
    520了,用32做个简单的小程序
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    MySQL 返回未包含在group by中的列
    《Mysql日志备份/恢复》大型详细攻略两万字图解(史上最详细,多图)
    年轻就该多尝试,教你20小时Get一项新技能
    Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
  • 原文地址:https://www.cnblogs.com/iexperience/p/9329362.html
Copyright © 2020-2023  润新知