关于一个容器的线程安全问题

时间:2011-08-12 23:15:49

标签: thread-safety critical-section

让我们谈谈理论。我们有一个容器,我们称之为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)。

问题:如果最后一个函数中没有关键部分,它是否是线程安全的?

1 个答案:

答案 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 - 这一切都取决于是否可以接受。