python3.6多进程导致的卡死报错问题

在使用python3.6的多进程的时候,遇到了进程卡死的问题。
具体表现为:多进程不停的开打爆了机器

排查后发现,原因是在使用apply_sync的时候,输入进去的参数大小太大导致的卡死,正常情况下应该是有这样的报错的:

python struct.error: ‘i’ format requires -2147483648 <= number <= 2147483647

原因是在使用pickling传输数据的时候大小太大超过限制爆掉了(这个问题升到3.8就可以解决)

但是由于我在传输数据的时候加入了multiprocessing.manager,加入后反而不会提示这个异常报错了,猜测是manager里加了处理,但是依然没有解决问题,运行的时候发现多进程依然没有正常运行和输出结果。

之后我还尝试了各种方法:
比如使用gc清理无效变量和内存

import gc
del a,b #a,b是占用内存大的变量名
gc.collect()

这么做有用,内存占用量减少但是还是无法正常处理多进程

然后又想到程序里用popen调用了shell命令,会不会是这个问题?在最后补上了清空Pipe的代码

with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as fp:
    try:
        num = 0
        while True:
            line = fp.stdout.readline()
            cmd_status = fp.poll()
            if not line and cmd_status is not None:
                break
            else:
                try:
                    s1 = str(line, encoding='utf-8')
                except:  # UrlEncodedFormEntity编码格式默认是iso_8859_1
                    s1 = str(line, encoding='iso_8859_1')
                    # 解析数量限制
                if num > 5000000 and '  },\n' == s1:
                    json_str += "}]"
                    parse_msg.append("1\t" + parse_status['1'] + "\texceed limit 5000000 lines")
                    break
                json_str += s1
    except Exception as e:
        parse_msg.append("3\t" + parse_status['3'] + "\tread json str error--" + str(e))
    finally:
        # 清除管道符里的输出并kill掉进程
        if fp.stdin:
            fp.stdin.close()
        if fp.stdout:
            fp.stdout.close()
        if fp.stderr:
            fp.stderr.close()
        try:
            fp.kill()
        except OSError:
            pass

还是没用,最后问了chatGPT,说建议使用Process+Queue来处理大量数据
最终解决了,原因应该是Queue使用的是Pipe没有触发pickle的大小限制报错,所以可以正常运行。

def Fun(n,output)
     result=1
     output.put(result)
all_result_list = []
output = Queue()
thread_list = []
for process_id in range(maxprocess_num):
    th = Process(target=Fun, args=(n, output))
    thread_list.append(th)
    th.start()

for th_item in thread_list:
    while th_item.is_alive():
        while not output.empty():
            all_result_list.append(output.get())

for th_item in thread_list:
    th_item.join()

然后又发现,由于在脚本运行途中读取了一个600M的文件,多进程的内存复制机制会导致占用的内存量暴增,这可咋办?
询问chatGPT,提示我使用shared_memory,再一搜脸又黑了:这是python3.8加入的特性,在多进程之间共享内存减少内存占用量

后来查找后发现3.6环境也可以用,就是非常复杂:
https://blog.csdn.net/TracelessLe/article/details/110101588

问题暂时解决了

你可能感兴趣的:(json,python,开发语言)