Python Pool 用进程池多进程下载git 代码时hang 在read系统调用上。

发布于 2022-09-12 00:46:58 字数 2359 浏览 26 评论 0

我用Python多进程来clone git 代码,其中多进程的实现使用了Python Pool,一般情况下可以顺利的下载所有的代码,但是当存在其中某一个代码仓库的代码量远远大于其他代码仓库时,clone最大代码仓库的子进程会hang在git-lfs上,使用strace命令来追踪该git进程,可以看到它卡在read系统调用上。

Process 27649 attached
read(6, 0x7ffc36dae050, 4)              = ? ERESTARTSYS (To be restarted if SA\_RESTART is set)
--- SIGALRM {si\_signo=SIGALRM, si\_code=SI\_KERNEL, si\_value={int=2895997, ptr=0x2c307d}} ---
rt\_sigreturn()                          = 0
read(6, 0x7ffc36dae050, 4)              = ? ERESTARTSYS (To be restarted if SA\_RESTART is set)
--- SIGALRM {si\_signo=SIGALRM, si\_code=SI\_KERNEL, si\_value={int=2895997, ptr=0x2c307d}} ---
rt\_sigreturn()                          = 0
read(6, 0x7ffc36dae050, 4)              = ? ERESTARTSYS (To be restarted if SA\_RESTART is set)
--- SIGALRM {si\_signo=SIGALRM, si\_code=SI\_KERNEL, si\_value={int=2895997, ptr=0x2c307d}} ---
rt\_sigreturn()                          = 0
read(6, 0x7ffc36dae050, 4)              = ? ERESTARTSYS (To be restarted if SA\_RESTART is set)
--- SIGALRM {si\_signo=SIGALRM, si\_code=SI\_KERNEL, si\_value={int=2895997, ptr=0x2c307d}} ---
rt\_sigreturn()

我的多进程实现代码如下。

    p = Pool(processNum)
    LogInfo('Parent process %s.' % os.getpid())
    multi_res = [p.apply_async(runfunc, args=(
        incl_info, project_root, skip_dirs,)) for incl_info in incl_infos]
    LogInfo('Waiting for all subprocesses done...')
    p.close()
    p.join()
    
    # 处理返回信息
    resMesList = []
    for res in multi_res:
        resMes = str(res.get())
        if (resMes.find("Failed") != -1):
            #LogErr("Please check the password.")
            resMesList.append(resMes)

处理函数子进程只是新启动一个shell中git clone的subprocess.

def runfunc(incl_info,project_root,skip_dirs):
    if incl_info == 0:
        git_url = project_root["git_url"]
        dir_path = project_root["dir_path"]
        GitCloneInShell(git_url,dir_path)

def GitCloneInShell(git_url,dir_path):
        cmd = ("git clone %s %s " % (git_url, dir_path))
        LogInfo("git clone cmd : %s" % cmd)
        status = subprocess.call(cmd, shell=True)
        return status

猜想是否是因为子进程的输出缓冲区被沾满了,状态转换为wait?但是不太清楚该如何去修改。请问有遇到类似情况的朋友吗,求助。谢谢啦!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文