TThreadList的凝问

lenyunzi 2009-02-27 05:46:41
对TThreadList不熟悉,据说是线程安全的TList,不知确实否?

在网上查找到如下使用方法:

TThreadList *pThreadList = new TThreadList();

TList *pList = pThreadList->LockList(); //锁定

pList->Add(...); //操作

pThreadList->UnlockList(); //解锁



TList是非线程安全的,多线程使用时如下:

TCriticalSection *Lock_List = new TCriticalSection();
TList *pList = new TList();

Lock_List->Acquire(); //锁定

pList->Add(...); //操作

Lock_List->Release(); //解锁


以上两种使用有什么区别?
哪种效率更高?


而TThreadList中也有Add(),能否不加锁而直接如下使用?

pThreadList->Add(...)


以上都是在多线程中使用
...全文
198 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
僵哥 2009-02-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 lenyunzi 的回复:]
没有哪个线程会删除呀,我没有任何pList->Delete(i)或pList->Remove(...)操作呀

只在主线程中有Add(),其他线程只是读操作.


pList仅在程序关闭时才删除.

那么我上面的理解对了吗?
[/Quote]
对于一个List并不只是Delete/Remove会执行删除,List会预分配一定的内存,当预分配的内存不足时,如果要添加更多的对象就会进行重新分配,并且进行数据转移,类似这些机制,可以看看STL当中的实现。
lenyunzi 2009-02-28
  • 打赏
  • 举报
回复
没有哪个线程会删除呀,我没有任何pList->Delete(i)或pList->Remove(...)操作呀

只在主线程中有Add(),其他线程只是读操作.


pList仅在程序关闭时才删除.

那么我上面的理解对了吗?

僵哥 2009-02-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 lenyunzi 的回复:]
谢谢unsigned


我的实际应用是:

在主线程中:
pList->Add(...);


在主线程及子线程中:
MyClass *pTemp = (MyClass *)pList->Items[i]; //从pList中读取出类实例
pTemp->... //对该实例的成员变量进行修改操作

为了提高效率,只要不作Delete()操作,就可以不对pList进行锁定.

我的理解正确吗?
[/Quote]
如果你去访问的时候别人把Index=I以前的某个成员删除掉了,你会访问到的是哪一个?
lenyunzi 2009-02-28
  • 打赏
  • 举报
回复
谢谢unsigned


我的实际应用是:

在主线程中:
pList->Add(...);



在主线程及子线程中:
MyClass *pTemp = (MyClass *)pList->Items[i]; //从pList中读取出类实例
pTemp->... //对该实例的成员变量进行修改操作

为了提高效率,只要不作Delete()操作,就可以不对pList进行锁定.

我的理解正确吗?
僵哥 2009-02-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lenyunzi 的回复:]
我在链表List中保存了一些类的实例的引用指针,

如我已申明MyClass类,在List中保存:

TList *pList = new TList();

MyClass *pMyClass = new MyClass();

pList->Add(pMyClass);

//... 在不同时刻,pList中还加入了MyClass的其他实例


现在的问题是:

为了提高效率,只在pList->Add()或pList->Delete()时对该List进行锁定,

在多个线程进行读操作时不加锁,可以吗?
MyClass *pTemp = (MyClass *)pLi…
[/Quote]
其它都还有什么操作?如果是Add可能不会影响其它线程对现有对象的操作,那要是Delete呢?当A线程在操作O对象,而此时B线程却Delete掉O,会有什么样的后果?
lenyunzi 2009-02-28
  • 打赏
  • 举报
回复
我在链表List中保存了一些类的实例的引用指针,

如我已申明MyClass类,在List中保存:

TList *pList = new TList();

MyClass *pMyClass = new MyClass();

pList->Add(pMyClass);

//... 在不同时刻,pList中还加入了MyClass的其他实例


现在的问题是:

为了提高效率,只在pList->Add()或pList->Delete()时对该List进行锁定,

在多个线程进行读操作时不加锁,可以吗?
MyClass *pTemp = (MyClass *)pList->Items[i];

对读取出的MyClass类实例中的相关变量进行修改操作(非删除该类实例),应该与pList无关了,理解正确吗?
也就是对pTemp->...进行操作



同一问题就放在同一贴子,分不够可以再加
僵哥 2009-02-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 lenyunzi 的回复:]
谢谢,

再请教,在多线程中:

TThreadList中也有Add(),能否不加锁而直接如下使用?

pThreadList->Add(...)
[/Quote]
看看二楼我贴的代码。
lenyunzi 2009-02-28
  • 打赏
  • 举报
回复
谢谢,

再请教,在多线程中:

TThreadList中也有Add(),能否不加锁而直接如下使用?

pThreadList->Add(...)


lenyunzi 2009-02-28
  • 打赏
  • 举报
回复
哦,是呀,这个倒没考虑到.
非常谢谢unsigned

僵哥 2009-02-27
  • 打赏
  • 举报
回复
TThreadList::Add的源代码(仅供参考)
procedure TThreadList.Add(Item: Pointer);
begin
LockList;
try
if (Duplicates = dupAccept) or
(FList.IndexOf(Item) = -1) then
FList.Add(Item)
else if Duplicates = dupError then
FList.Error(@SDuplicateItem, Integer(Item));
finally
UnlockList;
end;
end;

与之等价的C++代码
void __fastcall TThreadList::Add(void *Item)
{
LockList();
try{
if ((Duplicates == dupAccept) ||
(FList->IndexOf(Item) == -1))
FList->Add(Item);
else if (Duplicates == dupError)
FList->Error(&SDuplicateItem, (int)Item);
}__finally{
UnlockList();
}
}
僵哥 2009-02-27
  • 打赏
  • 举报
回复
一样。

13,824

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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