bash Windows XP 上的 Git sh.exe 进程分叉问题,速度慢吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5851611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:53:52  来源:igfitidea点击:

Git sh.exe process forking issue on windows XP, slow?

gitbashshellwindows-xpmsysgit

提问by AndyL

Git is essential to my workflow. I run MSYS Git on Windows XP on my quad core machine with 3GB of RAM, and normally it is responsive and zippy.

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

Suddenly an issue has cropped up whereby it takes >30 seconds to run any command from the Git Bash command prompt, including lsor cd. Interestingly, from the bash prompt it looks likes lsruns fairly quickly, I can then see the output from ls, but it then takes ~30 seconds for the prompt to return. If I switch to the windows command prompt (by running cmdfrom the start menu) git related commands also take forever, even just to run. For example git statuscan take close to a minute before anything happens. Sometimes the processes simply don't finish.

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

Note that I have "MSYS Git" installed as well as regular "MSYS" for things like MinGWand make.

请注意,我安装了“MSYS Git”以及常规的“MSYS”,例如MinGWmake

I believe the problem is related to sh.exelocated in C:\Program Files\Git\bin. When I run lsfrom the bash prompt, or when I invoke gitfrom the windows prompt, task manager shows up to four instances of sh.exeprocesses that come and go.

我相信问题与sh.exe位于C:\Program Files\Git\bin. 当我ls从 bash 提示符运行时,或者当我git从 windows 提示符下调用时,任务管理器最多显示四个sh.exe来来去去的进程实例。

Here I am waiting for lsto return and you can see the task manager has git.exerunning and four instances of sh.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

在这里我正在等待ls返回,您可以看到任务管理器git.exe正在运行和四个实例sh.exe在这里我在等待 ls 返回,您可以看到任务管理器有 git.exe 正在运行和 sh.exe 的四个实例

If I ctrl-cin the middle of an lsI sometimes get errors that include:

如果我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

Or for git status: $ git status

或用于git status: $ git status

sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable
sh.exe": fork: Resource temporarily unavailable

Can I fix this so that git runs quickly again, and if so how?

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

Things I have tried:

我尝试过的事情:

  • Reboot
  • Upgrade MSYS Git to most recent version & Reboot
  • Upgrade MSYS to most recent version & Reboot
  • Uninstall MSYS & uninstall and reinstall MSYS Git alone & Reboot
  • 重启
  • 将 MSYS Git 升级到最新版本并重新启动
  • 将 MSYS 升级到最新版本并重新启动
  • 卸载 MSYS 并单独卸载并重新安装 MSYS Git 并重新启动

I'd very much like to not wipe my box and reinstall Windows, but I will if I can't get this fixed. I can no longer code if it takes me >30 s to run git statusor cd.

我非常想不擦拭我的盒子并重新安装 Windows,但如果我不能解决这个问题,我会这样做。如果运行时间超过 30 秒,我将无法再编码git statuscd.

采纳答案by Greg Hewgill

Usually when a program takes 30 seconds to do something that should be instantaneous, it's more likely to be an I/O timeout problem, usually network, rather than the speed of your CPU or the amount of RAM you have. You may wonder how the network is involved, but that's a legitimate question (I wouldn't know for your system either).

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

Msysgit installs a special prompt that runs a special function __git_ps1that shows some useful information in the prompt. You can see this using echo $PS1, for my system this shows:

msysgit 安装了一个特殊的提示,它运行一个特殊的功能__git_ps1,在提示中显示一些有用的信息。您可以使用 看到这一点echo $PS1,对于我的系统,这显示:

$ echo $PS1
\[3]0;$MSYSTEM:\w
$ PS1='$ '
$
7 3[32m\]\u@\h \[3[33m\w$(__git_ps1)3[0m\] $

This extra information is totally optional and you can turn it off. So try the following in an Msysgit window:

此额外信息完全是可选的,您可以将其关闭。因此,请在 Msysgit 窗口中尝试以下操作:

$ __git_ps1
 (master)

This will reset the prompt to the default $and not try to run and commands inside the prompt. If this solves your delay problem, then it's likely to be the __git_ps1function. Try running it manually:

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

#Comment the lines below
#PS1='\[3]0;$MSYSTEM:\w
ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
ntoskrnl.exe!KeWaitForMutexObject+0x19f
ntoskrnl.exe!FsRtlCancellableWaitForMultipleObjects+0x5e
ntoskrnl.exe!FsRtlCancellableWaitForSingleObject+0x27 
7 #3[32m\]\u@\h \[3[33m\w$(__git_ps1)3[0m\] #$ '

and see how long it takes to return.

并查看返回需要多长时间。

You can fix this by removing the line that invokes __git_ps1from C:\Program Files\Git\etc\profile:

您可以通过删除行解决这个调用__git_ps1来自C:\Program Files\Git\etc\profile

##代码##

回答by user3817699

So we ran into this issue too, and I think we finally traced it down to msys's implementation of the Windows security model. I'll try to post a short summary of the issue:

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

Screenshot: Stack trace of stuck sh.exe. Note when msys-1.0.dll calls into NetServerEnum()

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

This is what's going on when sh.exe is blocked for 30 seconds. So NetServerEnum()is only called in msysin one place, security.cc:228in get_lsa_srv_inf(), which is called by get_logon_server()and get_logon_server_and_user_domain(), which is called in create_token(), which is called by seteuid()in syscalls.cc, which is called by setuid().

这就是 sh.exe 被阻止 30 秒时发生的情况。所以NetServerEnum()只能称为msys一个地方,security.cc:228get_lsa_srv_inf(),这是由所谓的get_logon_server()get_logon_server_and_user_domain(),这就是所谓的create_token(),这是由所谓seteuid()的syscalls.cc,这是所谓的setuid()

So essentially whats happening is that when the msys DLL is initialized and sh.exe tries to call setuid(), msys tries to faithfully abide by the Windows security model and tries to look up the list of domain servers from your domain/workgroup. Unfortunately unlike linux, for Windows this is a blocking call that takes 5-30 seconds to complete/timeout, and is actually rather unnecessary for well, git.

所以本质上发生的事情是,当 msys DLL 被初始化并且 sh.exe 尝试调用时setuid(),msys 尝试忠实地遵守 Windows 安全模型并尝试从您的域/工作组中查找域服务器列表。不幸的是,与 linux 不同,对于 Windows,这是一个阻塞调用,需要 5-30 秒才能完成/超时,实际上对于 git 来说是不必要的。

Our solution is to create new msys.dll with the security "feature" disabled by setting has_securityto false in winsup.cc. The bash/sh.exe that came with msysgit wasn't compatible with our new version of msys.dll, so we had to compile a new bash.exe from scratch too, no idea why. The end result was sh.exe no longer tries to make these NetServerEnum calls and runs lickity split.

我们的解决方案是创建一个安全的“功能”通过设置禁用新msys.dll has_security在winsup.cc为false。msysgit 附带的 bash/sh.exe 与我们新版本的 msys.dll 不兼容,所以我们也不得不从头开始编译一个新的 bash.exe,不知道为什么。最终结果是 sh.exe 不再尝试进行这些 NetServerEnum 调用并运行 lickity split。

回答by Matthew Skelton

If the slowdown is seen when running multiple simultaneous Git commands, it could be due to a kernel locking issue within msysgit

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

We saw that under some conditions, multiple instances of git.exe would all wait on the same kernel object (inside WaitForSingleObject()), effectively meaning that only a single git command could be run on the system at a time.

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

See here:10 git.exe processes all waiting on a single kernel object

看这里:10 个 git.exe 进程都在等待一个内核对象

Using ProcessExplorer, we could see all the git.exe processes were stuck here:

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

##代码##

This seems to be related to this issue: http://code.google.com/p/msysgit/issues/detail?id=320in that it's not Git but the pseudo-Linux runtime (mingw) which appears to contain the problem.

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

We changed the user account used to run the applications from SYSTEM to an interactive user account, and the kernel object waits went away:

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

Healthy git.exe processes git.exe processes spawning happily

健康的 git.exe 进程 git.exe 进程愉快地产卵

Therefore, the slowdown you are seeing COULD be related to some kind of kernel object contention - only when the previous git command has released the kernel lock might other commands be able to run.

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

Try changing the user account under which you are running the git commands, and see if this solves the issue - it did for us.

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

回答by Tony

Although Greg's answer solves the immediate speed issue I felt it is only masking the problem and not solving it.

尽管 Greg 的回答解决了眼前的速度问题,但我觉得它只是掩盖了问题,并没有解决问题。

I started having git bash run slowly and following the steps Greg describes did identify __git_ps1as being the culprit.

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

Rather than modifying the command prompt info (I find it useful to have the information it displays) I found a solution which worked for me, described in a blog post:

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

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

以域用户身份登录时Git bash变慢的解决方法

Searching the internet a bit, i found that git uses the default home, on my account set to be a network account. This ment that git would look in this directory all the time, causing the delay.

To fix this i created a local user environment variable, overriding the default one, and setting it to %USERPROFILE% which points at c:\users[username].

在互联网上搜索了一下,我发现 git 使用默认主页,在我的帐户上设置为网络帐户。这说明 git 会一直在这个目录中查找,从而导致延迟。

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

The same solution was also posted on SO answering a similar question.

同样的解决方案也发布在 SO 上,回答了类似的问题

Adding the environment variable returned git to full speed and I still get the command line information.

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

回答by murrayh

I had slow process forking problems on a Windows XP machine. Occasionally a process fork would take minutes.

我在 Windows XP 机器上遇到了缓慢的进程分叉问题。有时,进程分叉需要几分钟。

The fix for me was to empty out the computer's TEMP folder. The computer was a shared resource and had been accumulated files in there over some years.

我的解决方法是清空计算机的 TEMP 文件夹。计算机是共享资源,并且已经在那里积累了多年的文件。

回答by Arrigo Zanette

If sh hangs enumerating logon servers in NetServerEnum, try setting the LOGONSERVER environment variable to the actual logon server.

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