AWS Lambda - Python 中的多重处理,子级通过管道 send() 数据,父级在 recv() 中获取 EOFError 异常

问题描述 投票:0回答:1

我们有一个使用 Python 和多处理的 Lambda 函数。任务被分成多个块,每个块被委托给一个子任务。当子进程完成时,它通过共享连接(管道)发送()结果。 父级等待所有子级完成(join()),然后在所有管道上执行recv()。

直到上个月一切都很顺利。现在,在每次第一次 Lambda 尝试时,第一个父级 recv() 都会收到 EOFError,这会导致我们的 Lambda 执行失败。奇怪的是,第二次尝试时,一切正常。

子代码以此结束:

conn.send([csv_data])
conn.close()

父代码在recv()上失败

for process in processes:
    process.join()        

csv_data = parent_connections[0].recv()[0]

父连接和子连接是管道的末端:

parent_conn, child_conn = Pipe()

我们看到的异常:

: EOFError
...
    csv_data = parent_connections[0].recv()[0]
  File "/var/lang/lib/python3.6/multiprocessing/connection.py", line 250, in recv
    buf = self._recv_bytes()
  File "/var/lang/lib/python3.6/multiprocessing/connection.py", line 407, in _recv_bytes
    buf = self._recv(4)
  File "/var/lang/lib/python3.6/multiprocessing/connection.py", line 383, in _recv
    raise EOFError
EOFError

当我们尝试将读取从第一个父连接移动到 try/catch 中以查看问题是否仅存在于第一次读取时。

for i in range(0, len(parent_connections)):
        try:
            result_from_child = parent_connections[i].recv()[0]
        except Exception as e:
            print("Exception while processing data from a child process: {}.".format(str(e)))

在此更改之后,我们注意到前 N 次读取总是失败,而之后的所有读取都成功。

任何帮助将不胜感激:

  1. 为什么最近(上个月)才开始发生?也许 Lambda 基础设施有一些变化?

  2. 为什么它只在第一次 Lambda 尝试时发生?第二次尝试总是成功(第一次总是失败)。

  3. 每个块都有固定的大小,并且随着总工作量的增加,创建的进程总数也在增加。问题可能与此有关吗?

python aws-lambda python-multiprocessing recv
1个回答
0
投票

家长收到响应后关闭孩子连接解决了我的问题。

为什么会发生这种情况? - 疯狂的猜测
我最好的猜测是,第一次调用 lambda 时,通过管道进行通信会出现延迟。由于子级在父级接收之前关闭连接,因此会引发 EOFError。

解决方案
将所有子连接存储在列表中(就像父连接一样)并在父收到响应后关闭相应的子连接。

修改子代码

child.send(data)

修改父代码

results[i] = parent_connections[i].recv() child_connections[i].close()
    
© www.soinside.com 2019 - 2024. All rights reserved.