面试题答案
一键面试import multiprocessing
def sender(conn):
numbers = [1, 2, 3, 4, 5]
for num in numbers:
conn.send(num)
print(f"发送数字: {num}")
result = conn.recv()
print(f"接收结果: {result}")
conn.close()
def receiver(conn):
squared_results = []
while True:
if conn.poll():
num = conn.recv()
squared_results.append(num * num)
if len(squared_results) == 5:
conn.send(squared_results)
break
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = multiprocessing.Pipe()
p1 = multiprocessing.Process(target=sender, args=(parent_conn,))
p2 = multiprocessing.Process(target=receiver, args=(child_conn,))
p1.start()
p2.start()
p1.join()
p2.join()
关键步骤
-
创建管道:
parent_conn, child_conn = multiprocessing.Pipe()
使用
multiprocessing.Pipe()
创建一个管道对象,返回两个连接对象,parent_conn
和child_conn
,分别用于两个进程间的通信。 -
定义发送进程:
def sender(conn): numbers = [1, 2, 3, 4, 5] for num in numbers: conn.send(num) print(f"发送数字: {num}") result = conn.recv() print(f"接收结果: {result}") conn.close()
发送进程通过管道发送一系列数字,然后等待接收计算后的平方结果。
conn.send()
用于发送数据,conn.recv()
用于接收数据。 -
定义接收进程:
def receiver(conn): squared_results = [] while True: if conn.poll(): num = conn.recv() squared_results.append(num * num) if len(squared_results) == 5: conn.send(squared_results) break conn.close()
接收进程不断检查管道是否有数据到达(
conn.poll()
),如果有数据则接收(conn.recv()
),计算平方并存储,当接收到5个数字后,将计算结果发送回发送进程。 -
启动进程:
if __name__ == '__main__': p1 = multiprocessing.Process(target=sender, args=(parent_conn,)) p2 = multiprocessing.Process(target=receiver, args=(child_conn,)) p1.start() p2.start() p1.join() p2.join()
在
if __name__ == '__main__':
块中,创建并启动两个进程,分别传入对应的连接对象。p1.start()
和p2.start()
启动进程,p1.join()
和p2.join()
等待进程执行完毕。
注意事项
if __name__ == '__main__':
:在Windows系统上,必须将创建和启动进程的代码放在if __name__ == '__main__':
块中,这是因为Windows使用spawn
方式启动新进程,需要在主模块中进行必要的初始化。- 管道使用完毕后关闭:在每个进程中,使用完管道连接后需要调用
conn.close()
关闭连接,避免资源泄漏。 - 数据传输的阻塞:
conn.send()
和conn.recv()
默认是阻塞的。如果发送端在接收端准备好接收之前发送数据,发送端会一直阻塞,直到接收端调用conn.recv()
。同样,conn.recv()
也会阻塞,直到有数据可用。conn.poll()
可用于非阻塞地检查是否有数据可接收。