在Windows XP上Git sh.exe进程分叉问题,慢?

时间:2011-05-01 21:42:10

标签: git bash shell windows-xp msysgit

Git对我的工作流程至关重要。我在带有3GB内存的四核机器上运行Windows XP上的MSYS Git,通常它具有响应性和灵活性。

突然出现问题,从Git Bash命令提示符运行任何命令需要> 30秒,包括lscd。有趣的是,从bash提示符看起来像ls运行相当快,我可以看到ls的输出,但是提示返回需要大约30秒。如果我切换到Windows命令提示符(通过从开始菜单运行cmd)git相关命令也需要永远,甚至只是运行。例如git status可能会在发生任何事情之前花一分钟时间。有时这些过程根本无法完成。

请注意,我安装了“MSYS Git”以及MinGWmake之类的常规“MSYS”。

我认为该问题与位于sh.exe的{​​{1}}有关。当我从bash提示符运行C:\Program Files\Git\bin时,或者当我从Windows提示符调用ls时,任务管理器最多会显示四个git个进程实例。

我在等待sh.exe返回,您可以看到任务管理器已ls正在运行,有四个git.exe实例: Here I am waiting for ls to return and you can see the task manager has git.exe running and four instances of sh.exe

如果sh.exe位于ctrl-c中间,我有时会收到包含以下内容的错误:

ls

sh.exe": fork: Resource temporarily unavailable 0 [main] sh.exe" 1624 proc_subproc: Couldn't duplicate my handle<0x6FC> fo r pid 6052, Win32 error 5 sh.exe": fork: Resource temporarily unavailable : $ git status

git status

我可以解决这个问题,以便git再次快速运行,如果是这样的话?

我尝试过的事情:

  • 重新启动
  • 将MSYS Git升级到最新版本&amp;重新启动
  • 将MSYS升级到最新版本&amp;重新启动
  • 卸载MSYS&amp;卸载并重新安装MSYS Git alone&amp;重新启动

我非常想不擦拭我的盒子并重新安装Windows,但如果我不能解决这个问题,我会的。如果我需要> 30秒才能运行sh.exe": fork: Resource temporarily unavailable sh.exe": fork: Resource temporarily unavailable sh.exe": fork: Resource temporarily unavailable sh.exe": fork: Resource temporarily unavailable git status

,我就无法再编码

6 个答案:

答案 0 :(得分:7)

通常,当一个程序花30秒钟做一些应该是瞬时的事情时,它更可能是I / O超时问题,通常是网络,而不是你的CPU速度或你拥有的RAM量。您可能想知道网络是如何参与的,但这是一个合理的问题(我不知道您的系统)。

Msysgit安装一个特殊的提示符,它运行一个特殊的函数__git_ps1,在提示符中显示一些有用的信息。你可以使用echo $PS1看到这个,对于我的系统,它显示:

$ echo $PS1
\[\033]0;$MSYSTEM:\w\007 \033[32m\]\u@\h \[\033[33m\w$(__git_ps1)\033[0m\] $

这些额外信息是完全可选的,您可以将其关闭。所以在Msysgit窗口中尝试以下内容:

$ PS1='$ '
$

这会将提示重置为默认值$,而不是尝试在提示符内运行和命令。如果这可以解决您的延迟问题,那么它很可能是__git_ps1函数。尝试手动运行:

$ __git_ps1
 (master)

并查看返回所需的时间。

您可以通过从__git_ps1删除调用C:\Program Files\Git\etc\profile的行来解决此问题:

#Comment the lines below
#PS1='\[\033]0;$MSYSTEM:\w\007
#\033[32m\]\u@\h \[\033[33m\w$(__git_ps1)\033[0m\]
#$ '

答案 1 :(得分:7)

所以我们也遇到了这个问题,我认为我们最终将其追溯到msys的Windows安全模型的实现。我将尝试发布该问题的简短摘要:

屏幕截图: 堆栈的卡住sh.exe的痕迹。注意当msys-1.0.dll调用NetServerEnum()

当sh.exe被阻止30秒时,这就是正在进行的操作。因此NetServerEnum()仅在msys的{​​{1}} get_lsa_srv_inf() get_logon_server()中调用,get_logon_server_and_user_domain()调用create_token()seteuid()调用在setuid()中,由setuid()中的{{1}}调用,由{{1}}调用。

因此,最初发生的是当msys DLL初始化并且sh.exe试图调用{{1}}时,msys会尝试忠实地遵守Windows安全模型并尝试从您的域中查找域服务器列表域/工作组。不幸的是,与Linux不同,对于Windows而言,这是一个阻塞调用,需要5到30秒才能完成/超时,实际上对于git来说实际上是不必要的。

我们的解决方案是使用安全性&#34;功能&#34;创建新的msys.dll。在winsup.cc中将security.cc:228设置为false即可禁用。 msysgit附带的bash / sh.exe与我们新版本的msys.dll不兼容,所以我们不得不从头开始编译一个新的bash.exe,不明白为什么。最终结果是sh.exe不再尝试进行这些NetServerEnum调用并运行lickity split。

答案 2 :(得分:3)

如果在运行多个同步Git命令时看到减速,可能是由于msysgit中的内核锁定问题

我们发现在某些情况下,git.exe的多个实例都会在同一个内核对象上(在WaitForSingleObject()内)等待,这实际上意味着一次只能在系统上运行一个git命令

见这里:10 git.exe processes all waiting on a single kernel object

使用ProcessExplorer,我们可以看到所有git.exe进程都停留在这里:

ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
ntoskrnl.exe!KeWaitForMutexObject+0x19f
ntoskrnl.exe!FsRtlCancellableWaitForMultipleObjects+0x5e
ntoskrnl.exe!FsRtlCancellableWaitForSingleObject+0x27 

这似乎与这个问题有关:http://code.google.com/p/msysgit/issues/detail?id=320因为它不是Git而是伪Linux运行时(mingw)似乎包含问题。

我们将用于运行应用程序的用户帐户从SYSTEM更改为交互式用户帐户,并且内核对象等待消失:

健康的git.exe处理git.exe processes spawning happily

因此,您看到的减速可能与某种内核对象争用有关 - 只有当前一个git命令释放内核锁时,其他命令才能运行。

尝试更改运行git命令的用户帐户,看看这是否解决了问题 - 它为我们做了。

答案 3 :(得分:2)

虽然格雷格的答案解决了眼前的速度问题,但我觉得它只是掩盖了问题而没有解决问题。

我开始慢慢运行git bash并按照Greg描述的步骤确定__git_ps1是罪魁祸首。

而不是修改命令提示信息(我发现它显示的信息很有用)我找到了一个适合我的解决方案,在博客文章中有描述:

Solution to slow Git bash when logged in as a domain user

  

在网上搜索了一下,我发现git使用了默认的家,   在我的帐户上设置为网络帐户。这就是git会的   一直看这个目录,导致延迟。

     

为了解决这个问题,我创建了一个本地用户环境变量,覆盖   默认值,并将其设置为指向的%USERPROFILE%   C:\用户[用户名]

同样的解决方案也发布在SO answering a similar question上。

添加环境变量将git返回到全速,我仍然可以获得命令行信息。

答案 4 :(得分:0)

我在Windows XP计算机上的处理问题很慢。有时候进程分叉需要几分钟。

我的修复是清空计算机的TEMP文件夹。计算机是一种共享资源,并且在那里累积了多年的文件。

答案 5 :(得分:0)

如果sh挂起在NetServerEnum中枚举登录服务器,请尝试将LOGONSERVER环境变量设置为实际的登录服务器。