Git对于我的工作流程是必不可少的。我在具有3GB内存的四核计算机上运行MSYS Git在Windows上,并且正常情况下它响应性强,速度快。
突然出现了一个问题,在Git命令提示符中运行任何命令需要超过30秒,包括ls
或cd
。有趣的是,从bash提示符看来,ls
运行得相当快,然后我可以看到来自ls
的输出,但是提示符返回需要30秒左右。如果切换到windows命令提示符(通过从start菜单中运行cmd
),git相关命令也要花费很长时间,甚至只是运行。例如,git status
可以在任何事情发生前花费近一分钟的时间。有时候,这些过程根本就没有完成。
请注意,我已经安装了"MSYS“,以及像MinGW
和make
这样的常规"MSYS”。
我认为这个问题与位于C:\Program Files\Git\bin
的C:\Program Files\Git\bin
有关。当我从bash提示符运行ls
时,或者当我从windows提示符调用git
时,任务管理器就会显示来和去的四个sh.exe
进程实例。
在这里,我在等待ls
返回,您可以看到任务管理器正在运行git.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状态
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再次快速运行吗?如果是的话,如何解决?
我尝试过的事情:
我很想不要擦掉我的盒子,重新安装Windows,但是如果我不能修复它,我会的。如果运行git status
或cd.
需要超过30s,我就不能再编写代码了。
发布于 2011-05-01 22:15:28
通常,当一个程序花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\]
#$ '
发布于 2014-07-08 18:44:16
因此,我们也遇到了这个问题,我认为我们最终将其追溯到了msys实现Windows安全模型。我将试着发表一个简短的总结:
截图:
卡住sh.exe的堆栈跟踪。注意当msys-1.0.dll调用NetServerEnum()时
这就是当sh.exe被阻塞30秒时所发生的事情。因此,NetServerEnum()
只在msys
中被一个地方调用,security.cc:228在get_lsa_srv_inf()
中被get_logon_server()
调用,get_logon_server_and_user_domain()
在create_token()
中被调用,后者被seteuid()
在syscalls.cc中调用,后者被setuid()
调用。
所以从本质上说,当msys初始化并sh.exe试图调用setuid()
时,msys试图忠实地遵守setuid()
安全模型,并试图从您的域/工作组中查找域服务器列表。不幸的是,与linux不同的是,对于Windows来说,这是一个阻塞调用,需要5-30秒才能完成/超时,而且实际上对git来说也是不必要的。
我们的解决方案是创建新的msys.dll,通过在winsup.cc中将安全性设置为false,从而禁用安全“功能”。msysgit附带的bash/sh.exe与我们新版本的msys.dll不兼容,所以我们也必须从头编译一个新的bash.exe,不知道为什么。最终的结果是sh.exe不再尝试进行这些NetServerEnum调用并运行lickity。
发布于 2012-10-24 16:58:35
如果在运行多个同时执行的Git命令时出现减速,则可能是由于msysgit中存在内核锁定问题。
我们看到,在某些条件下,git.exe的多个实例都将等待同一个内核对象(在WaitForSingleObject()
中),这实际上意味着一次只能在系统上运行一个git命令。
见这里:
使用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)。
我们将用于运行应用程序的用户帐户从系统更改为交互式用户帐户,内核对象等待消失了:
健康git.exe过程
因此,您所看到的减速可能与某种类型的内核对象争用有关--只有当先前的git命令释放内核锁时,其他命令才能运行。
尝试更改运行git命令的用户帐户,看看这是否解决了问题--它确实解决了我们的问题。
https://stackoverflow.com/questions/5851611
复制相似问题