一个老问题:如何在多线程和Midas中进行数据库操作?

xiaojianw 2003-01-18 04:28:41
我搜了以前的帖子,可是对这个问题,大家的说法都不一样!

我现在的问题是
在多线程中,进行数据可操作,发上我以前的代码

void __fastcall TTokenRing::Execute()
{
int i;
while(!Terminated)
{
for(i=1;i<=SignalNumber;i++)
{
if((SignalList(i).Type>=0 && SignalList(i).Type<=MAXWAITTIMES)
|| SignalList(i).Type==SUCCESSCONNECTION)
{
varTRSignalID=SignalList(i).SID;
CommSvr->PutCommData(MakeNewTokenRing(TRSignalID));
LastRefashTime=Date()+Time();
GetBackTR=false;
Application->ProcessMessages();

while(!GetBackTR)
{
pLockDM->Acquire();

if(((Date()+Time())-LastRefashTime)>WaitLongestTime)
{
if(SignalList(i).Type==SUCCESSCONNECTION)
{
SignalList(i).Type=0;

sid=varTRSignalID;
type=0;
tm=0;

SysInfo->ISID =SysParaSvr->ServerID;
SysInfo->IDID =varTRSignalID;
SysInfo->User =" ";
SysInfo->IDateTime =Date()+Time();
SysInfo->IMessage =2;
SysInfo->IType =2; //cuo wu

Synchronize(RefashSignalType); //写数据库
Synchronize( SysInfo->WriteSystemInfo); //写数据库
pLockDM->Release();
break;
}

if(SignalList(i).Type>=0 && SignalList(i).Type<MAXWAITTIMES)
{
SignalList(i).Type++;

sid=varTRSignalID;
type=SignalList(i).Type;
tm=0;
Synchronize(RefashSignalType);
pLockDM->Release();
break;
}
else
{
SignalList(i).Type=-1;

sid=varTRSignalID;
type=-1;
tm=0;
Synchronize(RefashSignalType);

SysInfo->ISID =SysParaSvr->ServerID;
SysInfo->IDID =varTRSignalID ;
SysInfo->User =" ";
SysInfo->IDateTime =Date()+Time();
SysInfo->IMessage =3;
SysInfo->IType =1; //cuo wu

Synchronize( SysInfo->WriteSystemInfo);
pLockDM->Release();
break;
}
}

pLockDM->Release();
Application->ProcessMessages();
}
if(GetBackTR && SignalList(i).Type!=SUCCESSCONNECTION)
{
pLockDM->Acquire();
SignalList(i).Type=SUCCESSCONNECTION;

sid=varTRSignalID;
type=SUCCESSCONNECTION;
tm=Date()+Time();

Synchronize(RefashSignalType);

SysInfo->ISID =SysParaSvr->ServerID;
SysInfo->IDID =varTRSignalID ;
SysInfo->User =" ";
SysInfo->IDateTime =Date()+Time();
SysInfo->IMessage =1;
SysInfo->IType =3; //cuo wu

Synchronize( SysInfo->WriteSystemInfo);
pLockDM->Release();
}
}
}
Application->ProcessMessages();
}
}




这样写对吗?可是为什么程序运行得很慢?
...全文
128 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaojianw 2003-01-22
  • 打赏
  • 举报
回复
呵呵,问题解决了!
给分!!!!
请猛禽兄到
http://expert.csdn.net/Expert/topic/1373/1373651.xml?temp=.5541651
来领分!!
再次感谢猛禽兄的大力帮助!
xiaojianw 2003-01-22
  • 打赏
  • 举报
回复
猛禽兄:
你是对的!可是现在又出现了一个问题:我在程序里建立了三个线程,每个线程都有一个独立的DMoudle,运行没有什么问题,就是速度特别的慢,不只是为什么!你遇到过类似的问题吗?请指教,分不够可以在加!
猛禽 2003-01-21
  • 打赏
  • 举报
回复
你的做法还是错!

首先,把DataModule从你的自动创建列表中去掉,其次,不要在线程里再使用全局变量DMTRSignal,DM里有Connection/DataSet在DM创建时会自动创建的。
再看清楚我的代码吧:
class TMyThread : public TThead
{
private :
TMyDM * FDM; // 每个线程实例有自己的DM实例
...
};

__fastcall TMyThread::TMyThread( ... )
{
...
FDM = new TMyDM(NULL); // 在线程中创建DM,DM中的Connection/DataSet自动创建
}

__fastcall TMyThread::~TMyThread( )
{
delete FDM; // 因为这种DM不会自动释放,所以在线程结束前要释放它
...
}

__fastcall TMyThread::Execute()
{
...
FDM->DataSet1->Open( ); // 在线程中只使用自己的DM实例
...
}
猛禽 2003-01-20
  • 打赏
  • 举报
回复
在线程类中

#include "MyDataModule.h"

class TMyThread : public TThead
{
private :
TMyDM * FDM;
...
};

...

__fastcall TMyThread::TMyThread( ... )
{
...
FDM = new TMyDM(NULL);
}

__fastcall TMyThread::~TMyThread( )
{
delete FDM;
...
}

因为每个线程有自己的DM,互相不会干扰,就可以不用Synchronize或CriticalSection了.
当然,在DM里有各自的Connection/DataSet等.
xiaojianw 2003-01-20
  • 打赏
  • 举报
回复
猛禽兄:

按照你的方法还是不行,
运行到
DMTRSignal->CDSSignalManger->Active =false;

错误是“程序调用了另一个线程已经理的界面”

另外,你说在DM里有各自的Connection/DataSet等,
我实在DM中动态建立的,这样行吗?

__fastcall TDMSignal::TDMSignal(TComponent* Owner)
: TDataModule(Owner)
{
BaseConn=new TDCOMConnection(Owner);
CDSSignalManger=new TClientDataSet(Owner);
CDSSignalBase=new TClientDataSet(Owner);
CDSTodayIssues=new TClientDataSet(Owner);
CDSAvgIssues=new TClientDataSet(Owner);

}
xiaojianw 2003-01-20
  • 打赏
  • 举报
回复
如果不加Synchronize或CriticalSection,会不会在写库的时候出现错误呢?
cscer 2003-01-20
  • 打赏
  • 举报
回复
高手呢?

快来啊!

救命啊!
猛禽 2003-01-20
  • 打赏
  • 举报
回复
只有BDE才要这么麻烦,用ADO/DBX/IBX都不需要
gfh21cn 2003-01-20
  • 打赏
  • 举报
回复
多线程中操作数据库要创建多个会话对象
TSession,就可以了
猛禽 2003-01-18
  • 打赏
  • 举报
回复
在线程里用什么Application->ProcessMessages()?多余了吧。
有CriticalSecion就不用Synchronize了,要改进的话,最好每个线程创建自己的DataModule
xiaojianw 2003-01-18
  • 打赏
  • 举报
回复
另外,如果动态创建了DataModule,还需要做互斥和Synchronize吗?
xiaojianw 2003-01-18
  • 打赏
  • 举报
回复
TCriticalSection *pLockDM;
xiaojianw 2003-01-18
  • 打赏
  • 举报
回复
可是怎么动态创建一个DataModule呢?
我在程序里声明
TDMServer *DModule;
......
DModule->CDSAdmin......

这样编译通不过,说是找不到 DModule的定义


xiaojianw 2003-01-18
  • 打赏
  • 举报
回复
就是说,只需创建一个DataModule就可以了,而不需要在创建DataModule中的ClientDataSet了吗?

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧