让我们谈谈理论。我们有一个容器,我们称之为TMyObj,如下所示:
struct TMyObj{
bool bUpdated;
bool bUnderUpdate;
}
让一个名为TMyClass的类有一个容器数组,上面有+3个有用的函数。一个用于获取要更新的对象。一个用于向某个对象添加更新信息,另一个用于获取更新的对象。它也按此顺序调用。这是班级
class TMyClass{
TmyObj entries[];
TMyObj GetObjToUpdate;
{
//Enter critical section
for(int i=0; i<Length(entries); i++)
if(!entries[i].bUnderUpdate)
{
entries[i].bUnderUpdate=true;
return entries[i];
}
//Leave critical section
}
//the parameter here is always contained in the Entries array above
void AddUpdateInfo(TMyObj obj)
{
//Do something...
//Enter critical section
if(updateInfoOver) obj.bUpdated=true; //left bUnderUpdate as true so it doesn't bother us
//Leave critical section
}
TmyObj GetUpdatedObj
{
//<-------- here
for(int i=0; i<Length(entrues); i++)
if(entries[i].bUpdated) then return entries[i];
//<-------- and here?
}
}
现在想象5个线程使用前两个线程,另一个线程用于在上面一个类的一个实例上使用最后一个函数(getUpdadtedObj)。
问题:如果最后一个函数中没有关键部分,它是否是线程安全的?
答案 0 :(得分:0)
鉴于您的示例代码,它似乎对读取是线程安全的。这假设entries[]
是固定大小。如果你只是迭代一个固定的集合,没有理由要修改集合的大小,因此使线程安全的读取确定。
我唯一能看到的结果可能是过时了。问题来自对GetUpdatedObj
的调用 - Thread A
在
entries[0]
的更新
for(int i=0; i<Length(entrues); i++)
if(entries[i].bUpdated) then return entries[i];
如果Thread B
出现并在entries[0]
时更新i > 0
- 这一切都取决于是否可以接受。