Delphi中如何多线程 *** 作数据库中的数据表

Delphi中如何多线程 *** 作数据库中的数据表,第1张

1。通过线程的互斥来同步 *** 作数据库 2。数据库采用事务处理表中的数据 3。采用共享方式打开数据库,不是以独占方式打开数据库 建立一个mysql连接表加上一个临界区,表结点是这样的(mysqlcon,bool),根据实际情况定大校我用的是10个连接。

在编写多线程应用程序时 最重要的是控制好线程间的同步资源访问 以保证线程的安全运行 Win API提供了一组同步对象信号灯(Semaphore) 互斥(Mutex) 临界区(CriticalSection)和事件(Event)等 用来解决这个问题

Delphi分别将事件对象和临界区对象封装为Tevent对象和TcritialSection对象 使得这两个对象的使用简单且方便 但是如果在Delphi程序中要使用信号灯或互斥等对象就必须借助于复杂的Win API函数 这对那些不熟悉Win API函数的编程人员来说很不方便 因此 笔者用Delphi构造了两个类 对信号灯和互斥对象进行了封装(分别为TSemaphore和TMutex) 希望对广大Delphi编程人员有所帮助

一 类的构造 我们先对Win API的信号灯对象和互斥对象进行抽象 构造一个父类THandleObjectEx 然后由这个父类派生出两个子类Tsemphore和Tmutex

类的源代码如下

unit SyncobjsEx

interface

uses Windows Messages SysUtils Classes Syncobjs

type

THandleObjectEx = class(THandleObject)

// THandleObjectEx为互斥类和信号灯类的父类

protected

FHandle: THandle

FLastError: Integer

public

destructor Destroyoverride

procedure Release

override

function WaitFor(Timeout: DWORD): aitResult

property LastError:Integer read FLastError

property Handle: THandle read FHandle

end

TMutex = class(THandleObjectEx)//互斥类

public

constructor Create(MutexAttributes: PSecurityAttributes

InitialOwner: Booleanconst Name:string)

procedure Release

override

end

TSemaphore = class(THandleObjectEx)

//信号灯类

public

constructor Create(SemaphoreAttributes: PSecurityAttributes

InitialCount:Integer

MaximumCount: integer

const Name: string)

procedure Release(ReleaseCount: Integer= PreviousCount:Pointer=nil)

overload

end

implementation

{ THandleObjectEx }//父类的实现

destructor THandleObjectEx Destroy

begin

Windows CloseHandle(FHandle)

inherited Destroy

end

procedure THandleObjectEx Release

begin

end

function THandleObjectEx WaitFor(Timeout: DWORD): aitResult

//等待函数 参数为等待时间

begin

case WaitForSingleObject(Handle Timeout) of

WAIT_ABANDONED: Result := wrAbandoned

//无信号

WAIT_OBJECT_ : Result := wrSignaled

//有信号

WAIT_TIMEOUT: Result := wrTimeout//超时

WAIT_FAILED://失败

begin

Result := wrError

FLastError := GetLastError

end

else

Result := wrError

end

end

{ TSemaphore }//信号灯类的实现

constructor TSemaphore Create(SemaphoreAttributes: PSecurityAttributes

InitialCount MaximumCount: integerconst Name: string)//信号灯类的构造函数

begin

FHandle := CreateSemaphore

(SemaphoreAttributes InitialCount MaximumCount PChar(Name))

//四个参数分别为 安全属性 初始信号灯计数 最大信号灯计数 信号灯名字

end

procedure TSemaphore Release(ReleaseCount: Integer= PreviousCount:Pointer=nil)

//信号灯类的Release方法 每执行一次按指定量增加信号灯计数

begin

Windows ReleaseSemaphore(FHandle ReleaseCount PreviousCount)

end

{ TMutex }//互斥类的实现

constructor TMutex Create(MutexAttributes: PSecurityAttributes

InitialOwner: Booleanconst Name: string)

//互斥类的构造函数

begin

FHandle := CreateMutex(MutexAttributes InitialOwner PChar(Name))

end

procedure TMutex Release//互斥类的Release方法 用来释放对互斥对象的所有权

begin

Windows ReleaseMutex(FHandle)

end

end

二 信号灯对象与互斥对象的使用 信号灯对象

信号灯对象维持一个从 到指定最大值之间的数 在其计数大于 时是有信号的 而在其计数为 时是无信号的 信号灯对象可用来限制对共享资源进行访问的线程数量 例如应用程序可使用信号灯对象来限制它建立的窗口数量

用类的Create方法来建立信号灯对象 在调用该方法时 可以指定对象的初始计数和最大计数 该方法有四个参数 依次为 安全属性 初始计数 最大计数和对象名字(以便别的进程的线程可打开指定名字的信号灯句柄) 如

Semaphore := TSemaphore Create(nil )

一般把信号灯的初始计数设置成最大值 每次当信号灯有信号并等待函数返回时 信号灯计数就会减 而通过调用对象的Release方法可按指定量增加信号灯的计数(默认为加 ) 计数值越小就表明访问共享资源的程序越多 如 Semaphore Release( nil)其中第一个参数为增加的信号灯数量 第二个参数为执行该方法之前的信号灯数量 信号灯用法举例

if wrSignaled = Semaphore WaitFor( ) then//若信号灯是有信号的

begin

//打开另一个窗口

end

Semaphore Release()

在线程建立窗口之前 它使用WaitFor函数确定信号灯的当前计数是否允许建立新的窗口 等待时间设为 秒

互斥对象

Mutex对象的状态在它不被任何线程拥有时是有信号的 而当它被拥有时则是无信号的 Mutex对象很适合用来协调多个线程对共享资源的互斥访问(mutually exclusive) 例如 有几个线程共享对数据库的访问时 线程可以使用Mutex对象 一次只允许一个线程向数据库写入

用类的Create方法建立Mutex 对象 在建立Mutex 时 可以为对象起个名字 这样其他进程中的线程可以打开指定名字的Mutex对象句柄 例如

Mutex := TMutex Create(nil False )

在完成对共享资源的访问后 可以调用Release方法来释放Mutex 以便让别的线程能访问共享资源 如果线程终止而不释放Mutex 则认为该Mutex被废弃

互斥对象用法举例如下

if wrSignaled = Mutex WaitFor( ) then//若获得互斥对象的拥有权

begin

try

//往数据库写入

finally

Mutex Release//释放对互斥对象的拥有权

end

end

lishixinzhi/Article/program/Delphi/201311/8521

很简单,按如下5步,即可实现线程中连接DB:

1. 通过菜单->File->new->Other,新建一个thread object,线程类不妨命名为TThreadTest,单元名不妨另存为unitThreadTest

2. 在线程自动生成的Execute过程中撰写数据库连接代码

3. 在主窗体中引用线程单元:

use unitThreadTest

4. 在主窗体中定义一个线程变量ThreadTest:TThreadTest

5. 在主窗体的FormCreate过程中自动创建线程并让线程立即运行:

ThreadTest:=TThreadTest.Create(false)


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/10012638.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-04
下一篇2023-05-04

发表评论

登录后才能评论

评论列表(0条)

    保存