multithreading - Windows Server 2003上的多线程应用程序中的访问冲突

标签 multithreading arrays delphi

我有一个应用程序(使用Delphi 2009编写),该应用程序允许用户在选定的系统上运行查询,然后将结果合并到单个报告中。

应用程序的简要说明:
用户选择一个查询和一组要运行该查询的系统。通过创建一个新线程在其中运行查询,并使用TADOQuery在该线程内实际运行查询,可以在所有系统上同时运行该查询。查询完成运行后,将调用TADOQuery.SaveToFile,并将pfXML作为参数传递,以将结果保存到XML文档。一旦所有查询运行完毕,应用程序将解析所有XML文档并将它们合并为一个XML文档。然后,用户可以加载报表,该报表调用TADOQuery.LoadFromFile加载报表并将其显示在TListView中。

为了确保用户不会通过提交太多查询(从而启动太多线程)而不会使PC过载,我已经使用记录数组实现了一个队列。每个记录包含诸如查询名称,系统,状态(正在运行,已完成或未决)等信息。实现队列的另一个原因是用户可以同时提交多个查询(即,他们不必等待查询的时间)。第一个完成,然后再提交另一个)。记录数组可能不是实现队列的最有效方法,但它可以工作。我将并发运行的线程数保持为100(可由用户更改),并在运行线程结束时启动新线程,方法是将线程内查询的完成情况与管理队列的过程进行同步。内存使用量绝不会增加约25-30K。

最后一条相关信息是该应用程序还包含一个作业计划程序,该程序使用户可以指定何时运行查询。希望使软件在服务器上无人看管的情况下运行并每天在每天的特定时间每天创建报告的客户使用此功能。

问题:
该应用程序可以在Windows XP上正常运行。无论提交多少查询。但是,在Windows Server 2003上随机运行一段时间后,该应用程序将停止运行。尝试与应用程序进行交互(或将其关闭)将导致报告访问冲突。我无法终生确定它的来源或原因。

我的第一个想法是,它可能与操作系统中内存管理的实现有关,但我看不出是什么原因引起的。我已经在完全 Debug模式下使用FastMM4编译了该应用程序的一个版本,但它没有报告释放本不应该释放的内存的问题,或者在正常情况下运行时没有内存泄漏,因此尽管我仍然确定内存管理存在问题,但我看不到会发生什么。

我注意到发生访问冲突后,我的应用程序的temp文件夹中有很多报告文件(这意味着某些查询已运行并返回了结果,但并非所有线程都已完成并且报告还没有尚未合并)。作业调度程序还报告运行状况良好,并将作业提交到队列中,但由于最大线程数(默认为100)正在运行(我一直在进行测试,每20个通过调度程序提交作业,因此尚未运行)分钟,然后将应用程序放置一整夜)。

这使我相信队列(记录数组)的处理可能存在问题。如果线程完成并与管理队列的过程同步,但是队列有问题,则不会启动下一个线程,并且由于并非所有查询都已完成,因此temp文件夹中的报告将赢得不会被合并。这似乎是应用程序卡住的地方。

因此,我有两个问题:
1.是什么原因导致访问冲突?与队列有关,还是可能与其他有关?
2.为什么该应用程序在Windows XP上可以正常运行,但在Windows Server 2003上却无法运行?

更新
在测试过程中,我设法对应用程序进行了一定程度的设置,以至于现在我也可以在Windows XP上产生该错误,因此它似乎并不局限于Windows Server2003。它似乎出现在Windows Server 2003上比XP快得多。

如果我在一组系统上运行一组查询,请等到所有报告创建完毕后再重复该过程,最终,查询只是停止提交,并双击应用程序中的任何位置(并尝试关闭),结果是:一个访问冲突(总是写,尽管内存地址有所不同,并且并不总是写地址0)。

我已经使用MadExcept跟踪了调用堆栈,它没有显示任何异常-仅触发了双击事件的代码行。

某种情况正在阻止正在提交的查询,并且(我想)还会导致访问冲突,但是我看不出它可能是什么。

最佳答案

除了实际答案外,更多的是故障排除技巧...
对于#2,硬件是否相同?如果没有,那可能确实是单核与多核(或处理器)的问题。由于它是一个多线程应用程序,因此期望它在多个处理器/内核中表现出不同的行为也不是没有道理的。因此,请确保您没有用太多变量(硬件还是操作系统)来使问题蒙上阴影。

关于multithreading - Windows Server 2003上的多线程应用程序中的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4313886/

相关文章:

c# - 调用线程无法访问此对象,因为另一个线程拥有它 - BackgroundWorker 错误

c - 函数指针的问题

forms - DELPHI 将一个表单拖放到另一个表单中

delphi - 为什么编译器说我的表单变量在我的过程中未声明?

delphi - 如何从 Delphi 10.1 Berlin 中的类助手访问私有(private)字段?

java - 如果两个线程连接在一起并且其中一个由于某种原因中止,会发生什么

c# - 您能想到 .NET 中具有同步上下文的事件模式吗?

java - 我想读取实时日志文件,并想搜索我在运行时创建的某些特定关键字

C++数组地址分配给指针

c - 如何从 C 中的二维字符数组中获取字符串?