一、创建管道的类
 
  1、管道的基本参数
 
        Pipe([duplex]):在进程之间创建一条管道,并返回元组(conn1,conn2),其中conn1,conn2表示管道两端的连接对象,强调一点:必须在产生Process对象之前产生管道
        
        参数介绍: dumplex:默认管道是全双工的,如果将duplex射成False,conn1只能用于接收,conn2只能用于发送。
                       
  2、主要方法
    
        <1> conn1.recv() - 接收conn2.send(obj)发送的对象。如果没有消息可接收,recv方法会一直阻塞。如果连接的另外一端已经关闭,那么recv方法会抛出EOFError。
        
        <2> conn1.send(obj) - 通过连接发送对象。obj是与序列化兼容的任意对象
 
        <3> conn1.close() - 关闭连接。如果conn1被垃圾回收,将自动调用此方法
 
        <4> conn1.fileno()  - 返回连接使用的整数文件描述符
        
        <5> conn1.poll([timeout])  - 如果连接上的数据可用,返回True。timeout指定等待的最长时限。如果省略此参数,方法将立即返回结果。如果将timeout射成None,操作将无限期地等待数据到达。
 
        <6> conn1.recv_bytes([maxlength])
            接收c.send_bytes()方法发送的一条完整的字节消息。maxlength指定要接收的最大字节数。如果进入的消息,超过了这个最大值,将引发IOError异常,并且在连接上无法进行进一步读取。如果连接的另外一端已              经关闭,再也不存在任何数据,将引发EOFError异常。
 
        <7> conn.send_bytes(buffer [, offset [, size]])
            通过连接发送字节数据缓冲区,buffer是支持缓冲区接口的任意对象,offset是缓冲区中的字节偏移量,而size是要发送字节数。结果数据以单条消息的形式发出,然后                 调用c.recv_bytes()函数进行接                   收    
 
        <8> conn1.recv_bytes_into(buffer [, offset])
             接收一条完整的字节消息,并把它保存在buffer对象中,该对象支持可写入的缓冲区接口(即bytearray对象或类似的对象)。offset指定缓冲区中放置消息处的字节位移。返回值是收到的字节数。如果消息长度 大于可用的缓冲区空间,将引发BufferTooShort异常。

 1 from multiprocessing import Process, Pipe
 2
 3 def f(conn):
 4     conn.send("Hello The_Third_Wave")
 5     conn.close()
 6
 7 if __name__ == '__main__':
 8     parent_conn, child_conn = Pipe()
 9     p = Process(target=f, args=(child_conn,))
10     p.start()
11     print(parent_conn.recv())
12     p.join()

  应该特别注意管道端点的正确管理问题。如果是生产者或消费者中都没有使用管道的某个端点,就应将它关闭。这也说明了为何在生产者中关闭了管道的输出端,在消费者中关闭管道的输入端。如果忘记执行这些步骤,程序可能在消费者中的recv()操作上挂起(就是阻塞)。管道是由操作系统进行引用计数的,必须在所有进程中关闭管道的相同一端就会能生成EOFError异常。因此,在生产者中关闭管道不会有任何效果,除非消费者也关闭了相同的管道端点。

 1 # 管道错误模拟
 2 def func1(conn1,conn2):
 3     try:
 4         msg = conn2.recv()
 5         print('>>>',msg)
 6
 7         #如果管道一端关闭了,那么另外一端在接收消息的时候会报错
 8         msg2 = conn2.recv() #EOFError
 9
10     except EOFError:
11         print('对方管道一端已经关闭')
12         conn2.close()
13
14 if __name__ == '__main__':
15     conn1, conn2 = Pipe()
16     p = Process(target=func1,args=(conn1,conn2,))
17     p.start()
18     conn1.send('小鬼!')
19     conn1.close()
20     # conn1.recv()  #OSError: handle is closed   如果管道已经关闭,再接收子进程消息报错

二、总结
  1、主进程将管道的两端都传送给子进程,子进程和主进程共用管道的两种报错情况,都是在recv接收的时候报错的:
    (1).主进程和子进程中的管道的相同一端都关闭了,出现EOFError;
    (2).如果你管道的一端在主进程和子进程中都关闭了,但是你还用这个关闭的一端去接收消息,那么就会出现OSError;
 
  2、解决方案
  所以你关闭管道的时候,就容易出现问题,需要将所有只用这个管道的进程中的两端全部关闭才行。当然也可以通过异常捕获(try:except EOFerror)来处理。
  虽然我们在主进程和子进程中都打印了一下conn1一端的对象,发现两个不再同一个地址,但是子进程中的管道和主进程中的管道还是可以通信的,因为管道是同一套,系统能够记录。    
  我们的目的就是关闭所有的管道,那么主进程和子进程进行通信的时候,可以给子进程传管道的一端就够了,并且用我们之前学到的,信息发送完之后,再发送一个结束信号None,那么你收到的消息为None的               时候直接结束接收或者说结束循环,就不用每次都关闭各个进程中的管道了。
            
  队列是有管道+锁实现的!进程间通信(IPC)方式二:管道(不推荐使用,了解即可),会导致数据不安全的情况出现,后面我们会说到为什么会带来数据 不安全的问题。
           
   待续......
 

转载于:https://www.cnblogs.com/hq82/p/9851633.html

43_并发编程-管道相关推荐

  1. 05 Python 并发编程(管道,事件,信号量,进程池)

    管道 Conn1,conn2 = Pipe() Conn1.recv() Conn1.send() 数据接收一次就没有了 from multiprocessing import Process,Pip ...

  2. 并发编程线程通信之管道流

    前言 在并发编程中,需要处理两个问题:线程之间如何通信及线程之间如何同步.通知是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里, ...

  3. 【并发编程三】C++进程通信——管道(pipe)

    [并发编程三]C++实现通信--管道(pipe) 一.管道(pipe) 二.匿名管道 1.简介 2.父子进程:匿名管道的通信过程? 3.相关函数 3.1.创建管道CreatePipe 3.2.写入管道 ...

  4. Python并发编程实例教程

    有关Python中的并发编程实例,主要是对Threading模块的应用,文中自定义了一个Threading类库. 一.简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态 ...

  5. golang并发编程goroutine+channel(一)

    go语言的设计初衷除了在不影响程序性能的情况下减少复杂度,另一个目的是在当今互联网大量运算下,如何让程序的并发性能和代码可读性达到极致.go语言的并发关键词 "go" go dos ...

  6. java内存栅栏_内存屏障(Memory Barriers/Fences) - 并发编程中最基础的一项技术

    我们经常都听到并发编程,但很多人都被其高大上的感觉迷惑而停留在知道听说这一层面,下面我们就来讨论并发编程中最基础的一项技术:内存屏障或内存栅栏,也就是让一个CPU处理单元中的内存状态对其它处理单元可见 ...

  7. 并发编程之多进程篇之四

    主要知识点:互斥锁.队列和生产者消费者模型 一.互斥锁 1.进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱 ...

  8. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型...

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  9. Java 面试知识点解析(二)——高并发编程篇

    前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...

  10. Python并发编程之多进程(二)

    十.进程同步 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理 ---------- ...

最新文章

  1. Eclipse中10个最有用的快捷键组合
  2. 并发--基本的线程机制
  3. 点开计算机桌面选项怎么不见了,电脑桌面上的图标都不见了该怎么办?
  4. android 之DatePicker以及TimePicker的用法
  5. Python基础知识之文件的读取操作
  6. mysql命令行查看表的触发器_Mysql事项,视图,函数,触发器命令(详解)
  7. 加速转型 高通绝地反攻
  8. leetCode:reverseInteger 反向整数 【JAVA实现】
  9. C语言课程设计学生考勤管理系统
  10. 【转】NB-IoT移远BC95使用小结
  11. python 英语分词_python 英文分词
  12. 【福利贴】教你如何移动联通电信免流
  13. 东北大学计算机硬件题库,东北大学20春学期《计算机硬件技术基础》在线平时作业123答案100...
  14. Linux桌面i3与i7,i3吊打i7?——你所不知的CPU型号后缀的秘密
  15. 【云原生】Hadoop HA on k8s 环境部署
  16. Lidar_imu自动标定源码阅读(二)——calibration部分
  17. 介绍自己过去现在和未来_过去,现在和未来
  18. 职业选手的。cfg怎么用_靠演技出道,用直拍疯狂吸粉:“姐圈”选手怎么就出圈了呢?...
  19. 百度API加载离线百度电子地图和卫星切片
  20. 强化学习系列(1) 基本概念

热门文章

  1. Undertow技术:为什么很多Spring Boot开发者放弃了Tomcat?
  2. 5个相见恨晚的Linux命令
  3. 这就是为什么IT人没有女朋友的原因!!
  4. 代码很烂,所以离职。
  5. 使用curl来调试你的应用
  6. 2019-05-22 Java学习日记 day12
  7. 什么时候用DFS,什么时候用BFS?(DFS和BFS的特点和异同)
  8. Git钩子:自定义你的工作流
  9. 没有资本怎么创业的思维:不是钱,是实现。
  10. iphone 推送服务--Apple Push Notification Service