Вопрос безопасности темы об одном контейнере - PullRequest
0 голосов
/ 13 августа 2011

Давайте немного поговорим о теории.У нас есть один контейнер, назовем его 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 голосов
/ 13 августа 2011

Учитывая ваш пример кода, кажется, что он будет поточно-ориентированным для чтения .Предполагается, что entries[] является фиксированным размером.Если вы просто перебираете фиксированную коллекцию, нет никаких причин, по которым размер коллекции должен быть изменен, что делает потокобезопасным read ok.

Единственное, что я могвидите, результат может быть устаревшим.Проблема возникает из-за вызова 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 - все зависит от того, считается ли это приемлемым или нет.

...