Syn*_*ech 24 windows-7 console process conhost
去年我编译了一个可以从闪存驱动器运行的便携式博客/网络服务器系统。它很棒,而且效果很好,尤其是在 XP 上。问题是,当它在 Windows 7 中运行时,每个控制台程序都会产生两个进程,进程本身,加上conhost.exe.
在便携式博客系统的情况下,它的每个服务器组件(MySQL 的mysqld.exe、Apache 的两个实例httpd.exe、VisualSVN 的两个实例visualsvnserver.exe和 PHP 的多个实例php-cgi.exe)都会产生一个 实例conhost.exe。此时(没有php-cgi.exe活动副本,我有五个conhost.exe正在运行的实例,几乎没有使用 CPU 周期,但消耗了 22MB 的内存(除了实际进程当前使用的 80MB)。
自从 Windows 7 发布后(我认为可能是从 Vista 开始),我曾多次试图弄清楚各种(新)主机进程(例如,、、 和)的确切用途以及它们是否真的有必要。我尝试杀死它们并发现控制台程序继续工作,无论是使用控制台窗口的程序还是不使用控制台窗口的程序(如服务器)。conhost.exedllhost.exetaskhost.exe
我已经很熟悉了csrss.exe?视窗 ? conhost.exe并且多次看到相同的(几乎是逐字逐句的)解释。问题是每个人都只是简单地复制粘贴相同的解释,这是没有帮助的。它只是说,在 XP 中,控制台应用程序“托管于”或“运行于” csrss.exe,但在 Windows 7 中,conhost.exe为了安全起见,它们被转移到了。安全方面是有道理的,但它没有说明托管它的含义或为什么/何时需要(或者如果不需要,是否可以避免它)。甚至 Raymond Chen对此事的讨论也掩盖了为什么控制台应用程序的托管方式完全不同。
我能找到的最接近详细的技术解释的是Microsoft 的博客文章,它似乎强化了这样一种观点,即它仅与控制台应用程序的 GUI 和窗口有关。这让我更加怀疑conhost.exe这些服务器这样的无窗口程序是否有必要。如果根本没有窗口,那我为什么要浪费资源并将进程空间与不必要的进程混为一谈?为什么 Windows 不能检测到什么时候不需要并避免它?SecurityMatt 的回应在技术解释方面也有点有用,但同样,我正在寻找的信息不够。
我不是唯一一个试图找出一种方法来阻止不必要的conhost. 此人询问禁用它,并被简单地告知“这是不可能的”,没有进一步的努力或考虑。Hugh D和“几乎不是一个特性”指出了大量冗余实例conhost(至少在csrss,只有一个副本运行)的问题,包括资源使用情况和子进程结束后的延迟实例。我 Laufer质疑是否/何时甚至需要。
如果它们在任何时候实际上都不是必需的(同样,我没有看到杀死它们的任何不良影响),那么我想我可以(非常令人恼火地)通过用运行服务器的批处理文件替换服务器来解决这个问题,等待,然后杀死conhost他们导致运行的副本。当然,这需要一种快速简便的方法来确定它是哪一个。FallenGameR询问如何获取conhost.exe与给定 PID 的控制台程序相关联的实例,但没有得到答案。我认为简单地检索父进程的 PID 应该可以解决问题(不,ProcessExplorer 不是一个选项,一个自动化/脚本化的解决方案是必需的),但这不仅需要创建某种框架来获取孩子的 PID(而不是简单地运行它并完成任务),而且还意味着找出一种方法使其兼容XP 也是如此(例如,检查父进程的映像名称)。这篇博文给出了一种方法,但它需要 PowerShell 并且并不理想,更不用说它没有说明运行脚本的后果。
也许微软认为没有人再使用命令提示符(*咳嗽*Windows 8*咳嗽*),因此认为给他们带来负担并不是什么大问题,但肯定存在多个控制台应用程序正在运行并且每个应用程序都在运行的情况产生一个额外的、消耗内存的、使用 PID 的进程是可怕的,并且试图解决它充其量是非常不方便的。
有没有人有关于此事的明确、权威的信息?同样,我已经阅读了通用解释;我想知道:
conhostconhostAar*_*ler 19
必须以不同方式处理控制台应用程序,因为在 NT 内核(它是所有 2000、XP、Vista、Windows 7 和 Windows 8 的基础)下,它们是二等公民。在 Unix 系统架构中,每个进程在创建时都附加了标准输入、输出和错误流;终端 IO 是根据这些流实现的(stdin 来自键盘,stdout/stderr 进入终端),并且不希望使用这些流或没有的进程需要额外的努力他们的文件描述符打开。
在 Windows NT 体系结构中,虽然它不是 VMS 的直系后代,但或多或少是由同一团队开发的,但事实恰恰相反;默认情况下,新生成的进程根本没有连接到它的 I/O 流,也没有“终端”这样的概念。希望以稍微更 Unixy 的方式运行的程序可能会请求(通过编译时声明)系统为它们创建一个控制台窗口,并连接到它的输入/输出流;系统会这样做,但是由于 Windows 与 Unix 不同,它不会免费为您提供终端,因此创建一个终端需要大量的额外工作,因此以前是csrss.exe,现在是conhost.exe。
至于两者之间的区别,您的“几乎没有功能”链接非常充分地解释了它;简而言之,它的存在是为了解决 Windows 高度隐秘的控制台 API 先前迭代中的安全漏洞,该漏洞允许在早于 Windows 7 的 NT 版本中进行特权升级。(仅供参考,Vista 没有conhost.exe,这适合其作为 NT 家族的 Windows Millennium 的地位。)
任何需要等效于 Unix stdin/stdout/stderr 的程序都需要一个控制台,因此需要一个conhost.exe. 来自 Unix 领域的移民,例如 Apache、PHP 等,将需要这些流,因此系统会自动实例化conhost.exe它们,无论它们是否实际显示窗口。理论上,可以修改例如 Apache 的源代码,使其不需要终端,并将其编译为 Windows GUI 应用程序而不是控制台应用程序,这样系统就不会觉得需要生成conhost.exe. 假设这在实践中也是可能的,似乎没有人足够关心这样做。也许你会是第一个。
杀死一个给定的对象conhost.exe几乎肯定会禁用该实例下正在运行的任何进程的控制台 IO。您可能并不关心这一点,因为您正在处理的服务器进程无论如何都不会在控制台 IO 流上做任何有趣的事情,所以可能没有理由不杀死它们的conhost.exes。如果有疑问,杀死他们,看看它是否会破坏任何东西。
conhost.exe当启动一个请求控制台 IO 的程序时,没有办法阻止 Windows 实例化;这样做的唯一方法是重新编译它,以便 Windows 不会将其视为控制台应用程序。但是,假设杀死给定服务器进程的父进程conhost.exe不会以您关心的任何方式损害其功能,您应该能够通过taskkill /f /im conhost.exe在运行提示或控制台窗口中发出来一次性杀死它们——最好是前者,因为一旦其父conhost.exe实例被杀死,后者可能会死亡,并且几乎肯定会停止工作。再次,如果有疑问,杀死他们,看看它是否会破坏任何东西。
以该DETACHED_PROCESS标志启动的控制台应用程序不会获得控制台或 conhost 子进程。问题是该标志不适用于孙子进程,因此它仅适用于您直接启动的进程(如果您甚至可以找到允许您指定此标志的实用程序)。
另一个可能有效的选项是控制台进程调用该FreeConsole()函数。一些服务器应用程序支持 -d 或 -detach 参数,但这在 *nix 系统上可能更常见......
| 归档时间: |
|
| 查看次数: |
14529 次 |
| 最近记录: |