好久没玩D了,我想请问下这种情况下是否有线程安全的问题?

jiju 2011-09-05 01:44:52
本来我觉得是没有的,突然想到好像大部分vcl都不是线程安全的,怕写了出问题,到时候难改(线程出问题报错莫名其妙的), 若按下面给的简单例子,我怕测试不出问题,所以,特请教各位,望给个明确答案。



{
4个类
TCCC包含一堆TBBB,TBBB又包含一堆TAAA
TMythread 也包含一堆TBBB,并且这一堆TBBB是 TCCC里面TBBB列表的一个子集,(相同的指针都指向同一个对象);
每个线程TMythread 操作的TBBB都不相同,
}

type
TAAA = (TPersistent)
public
procedure cal_andWritetoDataBase(); //内部计算并写入数据库
end;



TBBB = (TPersistent)
private
FAAAs:TList;
public
procedure AddAAA(Created_TAAAObject:TAAA); //加入 已经创建好的 TAAA对象
procedure Clear; //清除FAAA列表
function count:integer;
property AAAs[iIndex:integer]:TAAA read GetAAA write SetAAA;
end;


TCCC = (TPersistent)
private
FBBBs:TList;
public
procedure AddBBB(newValue:TBBB);//加入 已经创建好的 TBBB对象
procedure Clear;//清除FBBB列表
function count:integer;//列表大小;
property BBBs[iIndex:integer]:TBBB read GetBBB write SetBBB;
end;

TMyThread = class(TThread)
private
FBBBs:TList;
public
procedure AddBBB(newValue:TBBB);//加入 已经创建好的 TBBB对象
procedure Clear;//清除FBBB列表
function count:integer;//列表大小;

protected
procedure Execute; override;
end;

//TCCC 含有TBBB的一个列表,只在线程运行前和运行后操作TBBB,
//TCCC运行和操作都在在主线程,TBBB,TAAA创建和销毁都在主线程
//TMyThread 含有TBBB的一个列表,这个列表是TCCC列表的一个子集,在线程运行中进行操作

//主线程

var
CCC:TCCC;
mythread:array [0..5]of TMyThread ;
procedure initClass()
var
AAA:TAAA;
BBB:TBBB;
i,j:integer;
begin
// CCC已创建
for i:=0 to 10 do
begin
BBB:=TBBB.create;
for i:=0 to 50 do
begin
AAA:=TAAA.create;
BBB.AddAAA(AAA) ;
end;
CCC.AddBBB(BBB);
end;

....
for i:=0 to CCC.count do
begin
mythread[i mod 5].AddBBB(CCC.BBB[i]);
end;
for i:=0 to 5 do
begin
mythread[i].Resume;
end;
end;

procedure TMyThread.Execute;
begin
for i:=0 to count do
begin
for j:=0 to TBBB(FBBBs.Items[i]).count do
TBBB(FBBBs.Items[i]).AAAs[j].cal_andWritetoDataBase(); //内部计算并写入数据库

end;
end;




请各位看下,哪里会出问题???凭空写的,部分细节错误不计算在内。



...全文
120 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiju 2011-09-16
  • 打赏
  • 举报
回复
真是年龄越大越晕头!!


to:funxu 你真热心。。。。
lght 2011-09-05
  • 打赏
  • 举报
回复
不是界面相关的控件,应该没有问题。

就看这个多线程数据库操作有没有问题了。
procedure cal_andWritetoDataBase(); //内部计算并写入数据库
funxu 2011-09-05
  • 打赏
  • 举报
回复
问题是针对某个Tlist实例,我实际操作的时候,仅仅只有某个线程能够操作这个tlist,所以我就想是不是真的要对tlist实现lock操作?
这个单线程就不用了
funxu 2011-09-05
  • 打赏
  • 举报
回复
1 如果你的线程a因为某些原因死锁了那么如果b访问a也会死锁,c访问b也会死锁
2 没看到你的线程释放代码
3 因为你在线程b的list访问线程a,那么当线程a被释放或者强制终止,那么线程b是否有相应的意外处理呢?同理c,另一方面从目前代码看,Lz如果要跨线程访问vcl的话,是会出错的
4 线程之间的无数据交互,都是写入数据库。但是写入是必须加锁的,因为写入操作是会发生数据库的共享违规的
jiju 2011-09-05
  • 打赏
  • 举报
回复
我这里说的vcl对象,不用考虑与界面相关的控件等,仅仅是一些 Tlist或者是TStringlist TQuery等东西

比如Tlist来说,我看d好像有个Tthreadlist,问题是针对某个Tlist实例,我实际操作的时候,仅仅只有某个线程能够操作这个tlist,所以我就想是不是真的要对tlist实现lock操作?
jiju 2011-09-05
  • 打赏
  • 举报
回复
To bdmh and m617105
对于写操作来说,我不可能到处都同步,如果写入的对象或数据结构只是在这个线程中使用我就不想同步。
问题是操作VCl对象可以这样吗?
jiju 2011-09-05
  • 打赏
  • 举报
回复
可能我没说明白,这段代码只是一个例子。也就是说如果在C语言下,我敢保证不会出问题,但是这里是从TPersistent继承下来的类,我不知道对这个类操作的时候会不会出问题。

我不是叫大家考虑我的程序的细节部分如何构建不会出问题,我想问的是

1.一个 从TPersistent继承下来的类,在主线程创建后,只在一个子线程中进行操作是否会出问题?
2.这个继承下来的类里面为了方便,使用TList,处理数据(TList),是否在子线程中操作这个TList会出问题?(读写TList),线程之间的无数据交互,都是写入数据库。

能不用加锁的地方,我不想加,要不然只要一操作这个类就加,那还写什么线程。
浩南_哥 2011-09-05
  • 打赏
  • 举报
回复
好长啊,确实没看到加锁的地方,在写的地方都加锁吧
bdmh 2011-09-05
  • 打赏
  • 举报
回复
从你的代码中看不到任何同步的信息,根本保证不了你的操作的顺序性,这对于读操作还好,但对于写操作问题很大
lyhoo163 2011-09-05
  • 打赏
  • 举报
回复
出试题呀!
funxu 2011-09-05
  • 打赏
  • 举报
回复
理论上assign后相当于完全复制到另一个里面,不过因为各个类都有重写,所以要看你的实例怎么实现assign的了
jiju 2011-09-05
  • 打赏
  • 举报
回复
to funxu
1,谢谢提醒,不过我主要不是问这个
2. 例子代码,只是让人理解而已
3. 没看懂
4. 数据库操作我加锁的

to lght
你别应该啊,我要确切的答案。


程序这部分实际还没写,我只完成了com组件(vc写的)的代码,因为这次要做界面和数据库,以前只用过d搞过,这次重新拿起来写。

我程序思路大概是这样的,(delphi部分)主程序创建一堆类实例,(比如10个),然后按某种规则把这10个分配到4个线程中去运行(计算,存储), 线程之间的数据交互不考虑。

我在写com组件的时候,在切换线程的时候需要不停的marshal com指针,所以我回到delphi,已经蒙了。 比如一个我主线程创建了一个TPersistent继承下来的类,我在线程中操作,比如使用Assign方法,是否会有不安全的因素在里面, 线程中操作的类对象仅仅是在这一个线程中使用,与其他线程无关。最后主线程释放这个对象。

我想知道一个确切的答案,否则写出来,出问题了麻烦!!!

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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