首页 > 解决方案 > Python 中的分段错误与对 Dialogflow 的多处理调用

问题描述

我很难理解为什么下面的代码会导致分段错误。

它似乎是不确定的,大约有 30% 的时间发生,我注意到如果我用线程替换进程,它就不会发生。(但我需要在我的特定应用程序中处理)。

下面的代码试图将错误与大型项目隔离开来(这很难做到),所以请注意可能有一些看起来不合逻辑或不完整的部分,我还添加了一些行来增加出错的机会(比如多次重复某事)。

为了运行代码,请使用您自己的 Dialogflow 凭据并相应PROJECT_ID地设置变量。AGENT_NAMEDIALOGFLOW_PROJECT_ID

我正在使用Python 3.8和包google-api-core==2.0.1google-auth==2.2.2google-cloud-dialogflow==2.7.1

import faulthandler
import os
import shutil
from multiprocessing import Process
from time import sleep

import google.cloud.dialogflow as dialogflow

os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = 'credentials.json'  # USE YOUR OWN
SESSION_ID = '0' 
PROJECT_ID = '####'    # USE YOUR OWN
AGENT_NAME = '####'    # USE YOUR OWN
DIALOGFLOW_PROJECT_ID = '###'    # USE YOUR OWN

session_client = dialogflow.SessionsClient()
session = session_client.session_path(DIALOGFLOW_PROJECT_ID, SESSION_ID)

faulthandler.enable(all_threads=True)

os.makedirs('dir_foo', exist_ok=True)
shutil.make_archive(f'agent_foo', 'zip', f'dir_foo')  # Make an empty zip file (mock agent)


def create_agent(language):
    print('Creating agent', AGENT_NAME)

    parent = "projects/" + PROJECT_ID
    agents_client = dialogflow.AgentsClient()

    agent = dialogflow.Agent(
        parent=parent, display_name=AGENT_NAME, default_language_code=language, time_zone="GMT"
    )

    print('Creating new agent')
    agents_client.set_agent(request={"agent": agent})

    return agents_client


def upload_bot(language):
    for i in range(5):
        agent = create_agent(language)
        encoded_string = open(f"agent_foo.zip", "rb").read()

    request = {
        "parent": f'projects/{PROJECT_ID}',
        "agent_content": encoded_string
    }
    print('Uploading...')
    for i in range(5):
        agent.restore_agent(request)
    print('Successfully updated bot!')


def execute():
    try:
        upload_bot('en')
    except Exception as e:
        print(e)


processes_list = list()
for i in range(16):
    t = Process(target=execute)
    t.start()
    processes_list.append(t)
    sleep(1)

for c in range(len(processes_list)):
    processes_list[c].join()

print('DONE')

这是错误消息:

Fatal Python error: Segmentation fault

Thread 0x00007f78a0d91740 (most recent call first):
File "#/.envs/project-name-3.8/lib/python3.8/site-packages/grpc/_channel.py", line 933 in _blocking
File "#/.envs/project-name-3.8/lib/python3.8/site-packages/grpc/_channel.py", line 944 in __call__
File "#/.envs/project-name-3.8/lib/python3.8/site-packages/google/api_core/grpc_helpers.py", line 66 in error_remapped_callable
File "#/.envs/project-name-3.8/lib/python3.8/site-packages/google/api_core/gapic_v1/method.py", line 142 in __call__
File "#/.envs/project-name-3.8/lib/python3.8/site-packages/google/cloud/dialogflow_v2/services/agents/client.py", line 511 in set_agent
File "#/bm/project-name/DEBUG_segfault.py", line 35 in create_agent
File "#/bm/project-name/DEBUG_segfault.py", line 42 in upload_bot
File "#/bm/project-name/DEBUG_segfault.py", line 57 in execute
File "/usr/lib/python3.8/multiprocessing/process.py", line 108 in run
File "/usr/lib/python3.8/multiprocessing/process.py", line 313 in _bootstrap
File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 75 in _launch
File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 19 in __init__
File "/usr/lib/python3.8/multiprocessing/context.py", line 276 in _Popen
File "/usr/lib/python3.8/multiprocessing/context.py", line 224 in _Popen
File "/usr/lib/python3.8/multiprocessing/process.py", line 121 in start
File "#/bm/project-name/DEBUG_segfault.py", line 65 in <module>'

标签: pythongoogle-cloud-platformsegmentation-faultmultiprocessingdialogflow-es

解决方案


推荐阅读