- 小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
♈ one进程间通信
⚽ 使用Queue(队列)实现进程间通信
-
multiprocessing模块中的Queue类可以实现进程间通信 -
Queue类方法介绍from multiprocessing import Queue Obj = Queue()-
Obj.put(item, block=True, timeout=None)
item添加队列;block当参数为true时,一旦队列被写满,则代码就会被阻塞,直到有进程取走数据并腾出空间给Obj使用;timeout参数用来设置阻塞的时间,即程序最多在阻塞timeout秒之后,如果还没有空间空闲,则程序会抛出queue.Full异常。 -
Obj.get(block=True, timeout=None) 从队列中删除并返回项目; 如果可选参数
block为true,timeout为None(默认值),如有必要,请阻止,直到项目可用。 -
Obj.put_nowait(item) 在不阻塞的情况下将项目放入队列。仅当可用插槽立即可用时才将项目排队。否则将引发完全异常。
-
Obj.get_nowait() 在不阻塞的情况下从队列中移除并返回项目。只有在立即可用的情况下才能获取项目。否则引发空异常。
-
Obj.empty() 队列是否为空判断,如果为空,则该方法返回值
True;反之,返回False。
eg:
from multiprocessing import Process, Queue, current_process def processFun(queue, name): print(current_process().pid, "进程放数据:", name) # 将 name 放入队列 queue.put(name) if __name__ == '__main__': # 创建进程通信的Queue queue = Queue() # 创建子进程 process = Process(target=processFun, args=(queue, "sun process")) # 启动子进程 process.start() # 该子进程必须先执行完毕 process.join() print(current_process().pid, "取数据:") print(queue.get())result:
5200 进程放数据: sun process 15152 取数据: sun process -
🏐 使用PIPE(管道)实现进程间通信
- 使用Pipe实现进程通信,首先需要调用
multiprocessing的Pipe()函数来创建一个管道。 eg:
conn1,conn2 = multiprocessing.Pipe(duplex=True)
-
conn1和conn2分别用来接收Pipe函数返回的两个端口;duplex参数默认为True,表示该管道是双向的,即位于 2 个端口的进程既可以发送数据,也可以接受数据,而如果将duplex值设为False,则表示管道是单向的,conn1只能用来接收数据,而conn2只能用来发送数据。 -
conn.send()发送数据 -
conn.recv()接收发过来的数据 -
conn.close()关闭连接 -
conn.poll()返回连接中是否还有数据可以读取 -
conn.send_bytes(buf, offset=0, size=None)发送字节数据。如果没有指定offset、size参数,则默认发送buffer字节串的全部数据;如果指定了offset和size参数,则只发送buffer字节串中从offset开始、长度为size的字节数据。通过该方法发送的数据,应该使用recv_bytes()或recv_bytes_into方法接收。 -
conn.recv_bytes(maxlength)接收通过send_bytes()方法发送的数据,maxlength指定最多接收的字节数。该方法返回接收到的字节数据。 -
conn.recv_bytes_into(buf, offset=0)功能与recv_bytes()方法类似,只是该方法将接收到的数据放在buffer中。
eg:
from multiprocessing import current_process, Pipe, Process
def processFun(conn, name):
print(current_process().pid, "进程发送数据:", name)
conn.send(name)
# conn.send_bytes(bytes(name))
if __name__ == '__main__':
# 创建管道
conn1, conn2 = Pipe()
# 创建子进程
process = Process(target=processFun, args=(conn1, "Sun Pipe Process"))
# 启动子进程
process.start()
process.join()
print(current_process().pid, "接收数据:")
print(conn2.recv())
# print(conn2.recv_bytes())
result:
4440 进程发送数据: Sun Pipe Process
3816 接收数据:
Sun Pipe Process
♉ two进程锁
- ⚾ 使用
Lock实现进程锁,首先需要调用multiprocessing的Lock来创建一个对象。使用Obj对象的acquire方法锁住进程。使用Obj的release方法释放锁。 eg:
from multiprocessing import Process, Lock
def f(Obj, i):
Obj.acquire() # 锁住进程
try:
print('hello world', i)
finally:
Obj.release() # 释放锁
if __name__ == '__main__':
Obj = Lock()
for num in range(10):
Process(target=f, args=(Obj, num)).start()
result:
hello world 6
hello world 4
hello world 7
hello world 3
hello world 2
hello world 1
hello world 8
hello world 9
hello world 5
hello world 0
♊ three生产消费者模型
- 🏀 创建
producer(生产者)函数和customer(消费者)函数
def producer(q, role):
print("start producer")
for i in range(10):
q.put(i) # 生产者
time.sleep(0.5)
print(f"{role} has set value {i}")
print("end producer")
def customer(q, role):
print("start customer")
while 1:
data = q.get() # 消费者
print(f"{role} has get value {data}")
- 🎳 创建一个队列,供生产消费者使用
Obj = Queue()
- 🏑 将生产消费任务添加到
Thread中
pro = Thread(target=producer, args=(Obj, "生产者")).start()
cus = Thread(target=customer, args=(Obj, "消费者")).start()
eg:
from multiprocessing import Queue
from threading import Thread
import time
def producer(q, role):
print("start producer")
for i in range(10):
q.put(i) # 生产者
time.sleep(0.5)
print(f"{role} has set value {i}")
print("end producer")
def customer(q, role):
print("start customer")
while 1:
data = q.get() # 消费者
print(f"{role} has get value {data}")
if __name__ == '__main__':
Obj = Queue() # 创建一个队列
pro = Thread(target=producer, args=(Obj, "生产者")).start()
cus = Thread(target=customer, args=(Obj, "消费者")).start()
result:
start producer
start customer
消费者 has get value 0
生产者 has set value 0
消费者 has get value 1
生产者 has set value 1
消费者 has get value 2
生产者 has set value 2
消费者 has get value 3
生产者 has set value 3
消费者 has get value 4
生产者 has set value 4
消费者 has get value 5
生产者 has set value 5
消费者 has get value 6
生产者 has set value 6
消费者 has get value 7
生产者 has set value 7
消费者 has get value 8
生产者 has set value 8
消费者 has get value 9
生产者 has set value 9
end producer