繁体   English   中英

Microsoft.NET和Doom的多核CPU

[英]Microsoft.NET and the Multicore CPU of Doom

问题是正确的

有没有人在单核机器上遇到过这种异常?

The I/O operation has been aborted because of either a thread exit or an application request.

一些背景

在单CPU系统上,一次只执行一条MSIL指令,尽管有线程。 在操作之间,运行时可以进行内务处理。

引进第二CPU(或第二芯),它能够具有一个操作执行运行时确实持家。 因此,在多核环境中执行时,在单个CPU机器上完美运行的代码可能会崩溃 - 甚至会导致蓝屏。

有趣的是,HyperThreaded Pentiums并没有表现出这个问题。

我的示例代码在单核上完美运行,并且在多核CPU上实现了分片。 它在某处,但我仍在努力找到它。 它的要点是,当它被实现为访问者模式时,它会在不可预测的迭代次数之后剥落,但是将方法移动到访问者操作的对象使得问题消失。

对我来说,这表明框架具有某种用于解析对象引用的内部哈希表,并且在多核系统上存在关于访问它的竞争条件。

我目前还有使用APM处理串行通信的代码。 它曾经在我的USB串口适配器的虚拟comport驱动程序中间歇性地蓝屏,但我通过在每个Stream.EndRead(IAsyncResult)之后执行Thread.Sleep(0)解决这个问题。

在随机的时间间隔,当调用AsyncCallback我提供给Stream.BeginRead(...)并且处理程序尝试调用Stream.EndRead(IAsyncResult) ,它会抛出一个IOException指出The I/O operation has been aborted because of either a thread exit or an application request.

我怀疑这也是多核相关的,某种内部错误正在杀死等待线程,导致这种行为。 如果我对此是对的,那么该框架在多核环境的背景下存在严重缺陷。 虽然有变通办法,如我刚才所说,你不能总是因为有时他们需要其他内部框架代码被应用应用它们。

例如,如果您在网上搜索上述IOException,您会发现它会影响那些显然甚至不知道他们使用多个线程的人编写的代码,因为它发生在框架便利包装器的封面下。

微软倾向于将这些错误报告作为不可复制的内容。 我怀疑这是因为问题只发生在多核系统上,而像这样的错误报告没有提到CPU的数量。

那么......请帮我解决问题。 如果我是对的,我将不得不用可重复的测试用例来证明它,因为我认为错误的是在框架和运行时都需要错误修正。


有人认为问题更可能是我的代码而不是框架。

调查问题的变体A,我已将问题代码移植到示例应用程序中并将其减少,直到剩下的只有线程设置和方法调用在一个CPU上工作而在两个上失败。

Variant BI尚未经过测试,因为我不再拥有任何单核系统。 所以我重复一个问题:有没有人在单个核心平台上看过这个例外?

不幸的是,没有人可以证实我的怀疑,只能反驳它。

告诉我自己容易犯错是没有用的,我已经意识到了这一点。

如果您知道将.NET应用程序固定到单个CPU的方法,那么解决这个问题会非常方便。 ---感谢VM的建议。 我会做到这一点,好的电话。

根据您的描述,我倾向于责怪COM端口驱动程序。 它的驱动力是在多核时代之前开发出来的吗? 我曾经遇到过这样一个类似的问题,后来的驱动程序修订得到了修复。

另外:要回答有关如何将应用程序限制为单个CPU的问题,您需要将进程关联性设置为单个CPU。 看到这个链接 您也可以在使用任务管理器开始流程后执行此操作(右键单击任务管理器中的流程并选择“设置亲和力...”)

蓝屏不仅仅是应用程序或框架中的错误。 蓝屏需要内核模式的“帮助”。 你的一个问题是一个有缺陷的驱动程序,无论哪个“时代”有缺陷的驱动程序被编码。

关于一个线程关闭端口而另一个线程仍在使用它的可能性,我认为这可能与框架内务中的一些着名错误有关。 我认为这些错误并不依赖于核心数量,但是当核心数量增加时,受这些漏洞攻击的频率可能会增加。 尝试添加GC.KeepAlive调用以防止框架过早删除您的端口。

我目前正在重写我们的应用程序中使用的整个文件传输堆栈。 通过与其他工作人员的对话,我知道几年前,当单核笔记本电脑和低速连接用于生产时,它有点工作。 现在每个人都转向双核和高速互联网,整个软件显示出不可预测的结果。

所以,当我开始更多地学习代码时,我发现开发它的人对于如何正确编写多线程代码没有一个想法 所有“同步”都是使用Thread.Sleep()完成的! 线程管理是在“即发即忘”的基础上完成的。 有人想停止线程吗? Thread.Abort的()! 该死! 这个该死的东西真的很令人惊讶。

我的观点是 - 去检查你的代码 ,如果你正在使用一些自定义硬件,他们的驱动程序代码。 问题在于,不是在.NET,Win32或其他地方。

在Vista之前,任何发出它的线程终止时正在进行的异步IO都将终止。 这往往会给出您报告的错误,即

由于线程退出或应用程序请求,I / O操作已中止。

我不确定这是否与你的问题有任何关系,但是你是否从一个可以在操作完成之前终止的线程发出异步操作?

我完全失去了言语。 你告诉你的代码在双核机器上破解了,你怀疑是MS的!

现在有一天,每台机器都有双核甚至四核。 如果.net框架在使用双核时遇到任何重大问题,那么为什么直播信使,现场编写器和许多其他.net厚应用程序不会频繁破解。 我相信SQL Server 2K5和2K8管理工作室也在.net中。 整个System.Web实现在C#本身。 整个Biztalk业务流程设计器位于.net中

现在来点。 您的应用程序似乎具有多线程和大量异步调用上下。 你有灵活配置没有。 您的应用程序中的线程? 如果是,可以将线程限制为1然后进行测试。 多线程导致的错误很难追踪。

你试过SOS吗? 尝试这样做......我不太了解谷歌,你肯定会获得有关SOS用法的良好资源。

作为最后的手段,打开一个MS支持案例。 你需要对他们很少耐心,因为一开始他们会从所有愚蠢的问题开始:)。 祝好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM