zoukankan      html  css  js  c++  java
  • python的进程间的数据交互

    #先来看下如何实现多进程

    # multiprocessing 这个是python的多进程的模块,我们会用到这个模块的很多方法
    from multiprocessing import Process
    import threading
    import time
    
    def f(name):
        time.sleep(2)
        print("hello,",name)
    
    if __name__ == '__main__':
        p1 = Process(target=f,args=("bob",))
        p2 = Process(target=f, args=("aob",))
        #多进程
    
        # p1 = threading.Thread(target=f,args=("bob",))
        # p2 = threading.Thread(target=f,args=("add",))
        # 多线程
        p1.start()
        p2.start()
        p1.join() 

    进程和进程之间是不能共享数据的,比如我们看下面的例子

    import multiprocessing
    from multiprocessing import Queue
    def test_func():
        test_queue.put("aa")
    
    if __name__ == '__main__':
        test_queue = Queue()
        test_func()
        print(test_queue.get())
    

      

    结果如下

    aa
    

      

    我们在看一个例子,通过子进程去运行函数test_func()

    import multiprocessing
    from multiprocessing import Queue
    def test_func():
        test_queue.put("aa")
    
    if __name__ == '__main__':
        test_queue = Queue()
        p = multiprocessing.Process(target=test_func)
        p.start()
        # test_func()
        # print(test_queue.get())
    

      

    下面我们来讲解下

    第一个例子,我们从头到尾只有一个进程在执行,所以在函数test_func中,可以直接使用外面定义的变量队列

    第二个例子,我们通过子进程去启动函数test_func,由于子进程和自己的父进程不是同一个进程,所以,在test_func中不能直接使用变量队列,运行脚本会直接报错的,此时我们如想在子线程中使用变量队列,就只能通过函数传参的方式将队列传递进去,就比如下面的例子

    import multiprocessing
    from multiprocessing import Queue
    def test_func(test_queue):
        test_queue.put("aa")
    
    
    if __name__ == '__main__':
        test_queue = Queue()
        p = multiprocessing.Process(target=test_func,args=(test_queue,))
        p.start()
        print(test_queue.get())
    

      

    #在看来子进程和父进程

    from multiprocessing import Process
    import os
    
    def info(title):
        print(title)
        print("module name,",__name__)
        print("parent process,",os.getppid())
        print("process id,",os.getpid())
        print("
    
    ")
    
    def f(name):
        info("function f")
        print("hello,",name)
    
    if __name__ == '__main__':
        info("main process line")
        #在主线程中调用info这个函数,所有这里执行的infor的函数的父进程是pycharm,而子进程id就是执行这个脚本的进程本身的id
    
        p = Process(target=info,args=("bob",))
        #这里是在多线程中调用info这个函数,调用info这个函数,那么在这里执行info这个函数,打印的父进程就是脚本本身这个进程id,而
        #这里的info函数的id就是一个新的进程id
    
        p.start()
        p.join()
    
    '''
    程序的执行结果如下
    main process line
    module name, __main__
    parent process, 3132
    process id, 9180
    
    bob
    module name, __mp_main__
    parent process, 9180
    process id, 5204
    
    '''
    

     

    #然后来看下通过Queue来实现进程之间数据交互

    #不同进程之间的内存数据是不共享的,可以用下面的方法实现进程间的内存共享,要通过一个第三方才能通信,这里我们介绍第一个方法:用队列Queue来实现
    #Queue有2个方法,一个put,一个是get,队列一定是先进先出
    from multiprocessing import Process
    from multiprocessing import Queue
    
    def f(q):
        q.put({"k1": "v1"})
        q.put(["1","2","3"])
        q.put(["2", "2", "2"])
    
        print(q.qsize())
        #获取队列queue的大小
    
    if __name__ == '__main__':
        que = Queue()
        que.qsize()
        p = Process(target=f,args=(que,))
        #这里执行这个函数,就是在执行这个脚本的进程id的子进程id
        p.start()
        print("from parent,",que.get())
        print("from parent,", que.get())
        #这里的进程id就是执行这个脚本的进程id
    #这里要注意,que.get如果拿不到数据,则会一直阻塞
    p.join() # 结果如下 ''' 2 from parent, {'k1': 'v1'} from parent, ['1', '2', '3 '''

    #通过pipe来实现进程之间交互

    #前面我们学习了进程之间交互数据的方法Queue,今天我们在来学习一下管道来实现进程之间的内存交互
    # pipe管道,也是进程间通讯的一种方式,会返回一对对象,2个对象分别是管道的两头,一个管道是有2头,一头赋值给子进程,一头赋值给你父进程
    from multiprocessing import Process
    #导入多进程这个方法
    
    from multiprocessing import Pipe
    #导入管道这个方法
    
    
    def f(conn):
        conn.send(["a","b","c"])
        conn.send(["1", "2", "3"])
        conn.close()
    #在子进程里send一个数据,然后关闭管道
    
    
    
    
    if __name__ == '__main__':
        parent_conn,child_conn = Pipe()
        #生成一个管道,一端是父进程,一端是子进程
        p = Process(target=f,args=(child_conn,))
        #用子进程启动函数f,f这个函数就往管道里send数据
        p.start()
        #启动上面定义的子进程
        print(parent_conn.recv())
        #通过父进程去管道中获取数据,并打印
        print(parent_conn.recv())
        # parent_conn.recv()
        # 这个recv这个方法也是阻塞的,如果没有recv到数据,则该管道会一直阻塞
        p.join()
        #等待这子进程执行完毕在退出
    

      

    判断pipe的缓冲区是否还有数据poll(timeout=xxx)方法

    import multiprocessing
    
    def test(conn):
    
        conn.send("123")
        conn.send("456")
        conn.close()
        print(conn.writable)
    
    
    if __name__ == '__main__':
        p_conn,c_conn = multiprocessing.Pipe()
    
        p = multiprocessing.Process(target=test,args=[c_conn,])
        p.start()
    
        # print(dir(p_conn))
        print(p_conn.recv())
        print(p_conn.recv())
        if not p_conn.poll(timeout=2):
            print("kong.....")
        p.join()
    
  • 相关阅读:
    兼容css3.0中的boxshadow
    获取页面和元素可视高度
    关于javascript中apply()和call()方法的区别
    BFC(Block Formatting Context)
    minheight最小高度的实现(兼容IE6、IE7、FF)
    sicily 1825. Nickname
    sicily 2000. Toy Shopping
    sicily 2075. 2.2 Computing the volume of a cylinder
    sicily 2001. Scavenger Hunt
    sicily 1608. Digit Counting
  • 原文地址:https://www.cnblogs.com/bainianminguo/p/7401954.html
Copyright © 2011-2022 走看看