天天看点

qtcpsocket类read函数接收大数据_Python 进程线程:使用PIPE交换数据

qtcpsocket类read函数接收大数据_Python 进程线程:使用PIPE交换数据

10305

进程之间交换对象

并行:同一时刻有多条指令在多个CPU上运行.

并行时常常需要进程之间交换数据,

multiprocessing

模块提供了2个

communication channels

来交换数据:队列

queue

和管道

pipe

qtcpsocket类read函数接收大数据_Python 进程线程:使用PIPE交换数据
除了上面两种交换数据的方式之外,进程之间也可以使用同步原语进行数据交换,但是要尽可能的避免使用同步原语,例如锁.因为

queue

pipe

效率上更高,更加安全.

1.使用队列

queue

来交换数据

queue

是多进程安全的队列,可以使用

queue

来实现多进程之间的数据传递.
  • put

    :此方法用来插入数据队列中,可选参数有两个:

    blocked\timeout

    • 如果

      blocked=True

      (默认值),并且

      timeout

      为正数,该方法会阻塞

      timeout

      指定时间.直到该队列有剩余的空间.如果超时,会抛出

      Queue.Full

      异常
    • 如果

      blocked=False

      ,但是该队列已满,会抛出

      Queue.Full

      异常
  • get

    :此方法可以从队列读取并删除一个元素.可选参数有2个:

    blocked\timeout

    • 如果

      blocked=True

      (默认值),并且

      timeout

      为正数,那么在等待时间内没有取到任何元素,会抛出

      Queue.Empty

      异常
    • 如果

      blocked=False

      ,如果

      queue

      有一个值可用,立即返回该值,否则,队列为空,会立即抛出异常

      Queue.Empty

常用属性和方法:

qsize()

返回队列的大小

empty()

返回布尔值,队列是否为空

full()

返回布尔值,队列是否满了

put(item[,block[,timeout]])

在队列中添加元素

item

put_nowait(item)

等价与

put(item, False)

get(item[,block[,timeout]])

在队列中删除元素并返回该元素的值

get_nowait()

等价与

get(Flase)

close() 表示该

queue

不加入新元素

join_theread()

加入后台线程,只能在调用

close()

后使用.它阻塞直到后台线程退出,确保缓冲区所有数据已经刷新到管道.默认情况下,如果进程不是队列的创建者,则退出.它将尝试加入队列的后台线程.

cancle_join_thread()

终止

join_thread()

防止后台线程在进程退出时被自动连接,可能会导致数据丢失

队列实例

执行结果:

生产者/消费者模式

以上就类似于生产者/消费者模式

它包含两类进程:一种只是用来生产数据,例外一种只是用来消费数据.为了串联他们,通常会采用共享的数据区域,就像一个仓库.生产者产生的数据都放入仓库中并不需要关注消费者的行为,消费者只需要从共享仓库中获取数据,并不需要关心生产者的行为.

而作为仓库关注的行为是:

  • 如果仓库共享数据区域已满的状态
  • 如果共享数据区域已空的状态
运行结果

Queue

在其中扮演了一个仓库的角色,就是用来处理共享数据的

2.使用

pipe

管道

Pipe

不是类,是函数,该函数定义在

multiprocessing\connection.py

中,返回一对通过管道连接的对象

con1

con2

,函数的原型是

Pipe()duplex=True

  • dublex=True

    (默认值):管道是双向的,处于全双工模式,

    con1\con2

    都可以收发数据
  • dublex=False

    ,管道是单向的,

    con1

    只能用于发送,

    con2

    只能用于接受

Pipe()

返回的是管道的两端,两端每个对象都有

send()

recv()

方法(还有其他方法),例如在全双工模式下,可以用

con1.send()

发送消息,

con2.recv()

接受消息,如果没有消息可以接受,

recv()

方法会一直阻塞,如果管道已经关闭,

recv()

会抛出

EOFError

异常

常用方法:

send(obj)

将一个对象发送到连接的另外一端

recv()

返回一个由另一端

send()

的对象,该方法会一直阻塞直到接收到对象,如果对端关闭了连接,或者没有东西可以接受,将抛出

EOFError

fileno

返回由连接对象使用的描述符

close()

关闭连接对象

poll()

返回连接对象是否有可以读取的数据.

1.主进程和子进程管道通信

需要注意的是,管道在建立的时候自动连接了主进程,不管是使用全双工,还是半双工,都需要对主进程的管道进行处理.

在全双工模式中,假设主进程是发送端,子进程是接收端

执行结果:

反之,主进程也能当接收端,子进程当发送端.

关闭管道后,

try

语句用于处理产生的

EOFError

异常

2.主进程闲置,2个子进程一发一收

在全双工模式下,就算主进程闲置,主进程也连接在管道的一端,既可以在接收端,也可以在发送端.需要自己去选择把握.

关闭管道后,

try

语句用于处理产生的

EOFError

异常

- END -

继续阅读