您的位置:首页 > 编程语言 > Python开发

Python多任务(五)-----4种进程间的通信(数据交换)Queue对象、管道Pipe、共享内存Value和Array、Manager对象 详解

2019-02-15 15:31 806 查看

进程间的通信(数据交换)

  • 现有2个进程A和B,他们都在内存中开辟了空间,那么我们在内存中再开辟一个空间C,作用是连接这两个进程的。对于进程来说内存空间是可以共享的(任何一个进程都可以使用内存,内存当中的空间是用地址来标记的,我们通过查找某一个地址就能找到这个内存)A进程可以不断的向C空间输送东西,B进程可以不断的从C空间读取东西,这就是进程间的通信。

Queue对象

  • 对Queue的认识和理解: Queue是复杂的数据结构的一种,即队列
  • 队列的特点是“先进先出(FIFO),后进后出(LILO)” 与 相反,栈的特点“先进后出,后进先出”
  • 使用如下:
  • 注意:创建的Queue对象是multiprocessing模块中的Queue类创建的对象。
  • import multiprocessing
    
    def send(q):
    # 发送数据
    s_msg = [11, 22, 33]
    for i in s_msg:
    q.put(i)
    print("---已发数据:%s---" % str(i))
    print("---数据发送完成---")
    
    def receive(q):
    # 接收数据
    r_msg = list()
    while True:
    r_msg.append(q.get())
    if q.empty():
    break
    print("---数据接收完毕:%s---" % str(r_msg))
    
    def main():
    # 创建一个队列
    # 注意:是multiprocessing模块中的Queue类
    q = multiprocessing.Queue()
    # 创建Process对象
    p1 = multiprocessing.Process(target=send, args=(q,))
    p2 = multiprocessing.Process(target=receive, args=(q,))
    # 创建、启动进程
    p1.start()
    p2.start()
    
    if __name__ =="__main__":
    main()

    管道Pipe

    • 管道在信息传输上是以流的方式传输, 也就是你从A进程不断的写入,B进程源源不断的读出,A进程先写入的就会被B进程先读出,后写进来的就会被后读出。
    • 管道本质: 在内存中开辟一个新的空间,对多个进程可见,在通信形式上形成一种约束。
  • 创建管道:
      导入multiprocessing模块中的 管道方法:Pipe(duplex)方法 参数:duplex默认值为True,表示管道为双向管道(全双工)如果设置为False则为单项管道(半双工)
    • 返回值:返回两个管道流对象,两个管道流对象分别表示管道的两端。 如果参数为True的时候,两个对象均可发送接收,
    • 如果为False时,则第一个对象只能接收,第二个就只能发送。
  • 创建管道对象,管道方法返回两个对象。
  • 利用send()方法、recv()方法向管道发送、接收数据。
      一次recv()只能接收一次send()的内容。
    • send()方法: 数据往管道里面送
    • send可以发送的数据类型比较多样,字符串,数字,列表
  • recv()方法:
      从管道中接收数据
    • recv()函数为阻塞函数,当管道中数据为空的时候会阻塞
    from multiprocessing import Process, Pipe
    
    def text(name, child_conn):
    print(name + ":开始执行...")
    print("--执行完成--" )
    # 向管道发送数据
    child_conn.send(name + "--OK--")
    
    if __name__ == "__main__":
    job = []
    # 使用全双工通信管道(Pipe()中duplex参数默认值为True)
    # 创建管道对象
    # Pipe() 该方法的返回值为两个管道对象
    child_conn, parent_conn = Pipe()
    for i in range(5):
    p = Process(target=text, args=(str(i+1), child_conn))
    job.append(p)
    p.start()
    # 从管道接收数据
    # 若管道中数据为空时发生阻塞
    for i in range(5):
    print(parent_conn.recv())

    共享内存Value、Array

    • Value、Array是通过共享内存的方式共享数据

    Manager对象

    • Manager是通过共享进程的方式共享数据。
    • Manager()返回的manager对象控制了一个server进程,此进程包含的python对象可以被其他的进程通过proxies来访问。从而达到多进程间数据通信且安全。
    • Manager对象控制一个拥有list、dict、Lock、Condition、Event、Queue等对象的服务端进程,并且允许其他进程访问这些对象。
    import multiprocessing
    from random import randint
    
    def text(d, key, value):
    d[key] = value
    
    if __name__ == "__main__":
    mgr = multiprocessing.Manager()
    d = mgr.dict()
    jobs = [multiprocessing.Process(target=text, args=(d, i+1, (i+1)**2)) for i in range(5)]
    for j in jobs:
    j.start()
    for j in jobs:
    j.join()
    print(dict(d))
    print("--- end ---")
  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: