Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 使线程使用中央数据库连接的正确方法_Multithreading_Delphi_Service - Fatal编程技术网

Multithreading 使线程使用中央数据库连接的正确方法

Multithreading 使线程使用中央数据库连接的正确方法,multithreading,delphi,service,Multithreading,Delphi,Service,我正在DelphiXe2中构建一个多线程服务应用程序。每根线都有自己的用途。主服务线程只负责保持其他线程运行并保存日志文件等。这些线程中的每个线程都通过同步事件触发器向主服务线程报告。这些线程在服务启动时创建,在服务结束时销毁 我想引入一个单独的线程作为集中式数据库连接,以避免创建许多TADOConnection实例。我的服务代码可以调用标准函数,例如UserListDataSet:=DBThread.GetUserList(SomeUserListDataSet)或者如果我可以发送直接的SQL

我正在DelphiXe2中构建一个多线程服务应用程序。每根线都有自己的用途。主服务线程只负责保持其他线程运行并保存日志文件等。这些线程中的每个线程都通过同步事件触发器向主服务线程报告。这些线程在服务启动时创建,在服务结束时销毁

我想引入一个单独的线程作为集中式数据库连接,以避免创建许多
TADOConnection
实例。我的服务代码可以调用标准函数,例如
UserListDataSet:=DBThread.GetUserList(SomeUserListDataSet)
或者如果我可以发送直接的SQL语句,比如
SomeDataSet:=DBThread.Get(MySqlText)。我还想避免太多的
CoInitialize()
等情况

作业线程将需要使用此db线程。我需要弄清楚如何“询问”它某些数据,“等待”响应,并在请求它的线程中“获取”该响应。我相信有很多方法可以做到这一点,但我需要知道哪种方法最适合我的场景。Windows消息?事件?我应该排队吗?它应该发送数据集还是其他什么?已经有什么可以做到这一点了吗?我需要弄清楚如何以一种可以从其他线程重用的方式构造这个DB线程

结构如下所示:

+ SvcThread
  + DBThread
    + TADOConnection
  + Thread1
  + Thread2
  + Thread3
我需要线程1、2和3向DBThread发送请求。当一个线程向它发送任何请求时,它需要等待直到得到响应。一旦有响应,DB线程需要通知询问线程。每个线程也可能同时向该DB线程发送请求


一个关于如何实现这一点的好教程将是完美的-它只需要适合我的场景。我不需要只知道“如何使两个线程一起通信”,而是“如何使多个线程与一个集中的数据库线程通信”。这些作业线程是作为主服务线程的子线程创建的,不属于db线程。db线程不知道作业线程。

通常,您会有一个存储所有请求的请求队列。数据库线程从队列中读取请求,处理它,然后调用请求者指定的回调例程来处理结果。不确定这如何映射到Delphi范例,但基本原理应该是相同的。

在等待从数据库获得响应时,是否有任何“请求”线程可以做一些有利可图的事情?如果答案是“不”,就像我怀疑的那样,那么也许您可以通过完全消除对“DB线程”的需求来简化您的情况。也许所有线程都可以依次共享一个数据库连接,使用互斥对象使它们“等待轮到它们”

在这种情况下,将有一个数据库连接,任何需要使用它的线程都会这样做。但是他们必须首先获得一个互斥对象,在执行数据库查询时保留互斥对象,然后释放互斥对象,这样下一个线程就可以轮到它了

如果您认为指定一个线程来管理连接是有利的(或必要的…),那么您可以使用(a)互斥来序列化请求,如前所述;和(b)一个事件对象,用于向DB线程发送已发布新请求的信号;和(c)另一个事件对象,用于向请求者发送已完成请求的信号


在这两种情况下,如果您确实确定请求者线程在此期间没有任何有用的事情可以做,那么在轮到它们之前,您会让线程“简单地休眠”。然后,他们直接或间接地做生意。没有“队列”,没有复杂的共享数据结构,仅仅因为您(比如…)确定不需要它们。

我认为使用DB连接池更适合您的问题。这还允许您以后扩展应用程序,而无需创建额外的DB线程,然后管理这些DB线程的“负载平衡”

既然您提到使用TADOConnection,请看一下Cary Jensen的这个实现。 我在几个应用程序中成功地使用了这个数据库连接池。我以几种方式修改了它,包括使用ini文件来控制:最大连接数、清理时间、超时时间等


Cary写了几篇文章作为它的文档。一个在这里。

本质上,因为我不能跨线程使用ADO组件,所以我正在寻找一种方法,将所有DB调用封装到自己的线程中。如果我可以将任何SQL语句发送到此线程并从中获取一些数据集,然后将这些数据集拉入另一个线程,那也太好了。我已经修改了这个问题,询问如何集中数据库连接以供多个线程使用。根据答案和注释,我想我可能会建立一个自己的数据库请求线程池。。。它设计的系统实际上非常大,数据库至少有12个以上的应用程序使用。说到这个,这就需要一个更加模块化的系统,其中EXE使用DLL,DLL在整个系统中封装通用功能。这是一个单独的问题,但是这个问题与使一个大型系统在模块化的基础上工作有很大关系。我有一个完整的开发框架来处理这个“开箱即用”的问题。每个线程实际上是一个线程消息队列,所有线程间通信都是基于消息的(没有同步方法)。请求/响应模式