Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.12.27;
Скачать: CL | DM;

Вниз

Использование общих переменных в различных потоках   Найти похожие ветки 

 
tipman   (2008-12-22 16:42) [0]

Есть массив. Объявлен глобально. Один поток загружает массив, другой потихоньку параллельно данные выуживает из него. Могут ли быть проблемы в данном случае, например, при одновременной попытке записать и считать данные разными потоками. И если да, то подскажите пожалуйста как это дело разрулить.
Спасибо


 
Сергей М. ©   (2008-12-22 16:47) [1]


> Могут ли быть проблемы в данном случае,


Могут.


> как это дело разрулить


Защитить операции записи и чтения критической секцией.

см. класс TCriticalSection

пример:

cs.Enter; //захват секции
try
.. любая операция с защищаемым ресурсом, в д.с. с глоб.массивом ..
finally
 cs.Leave; //освобождение секции
end;


 
Palladin ©   (2008-12-22 16:50) [2]


>  Могут ли быть проблемы в данном случае,

Запросто.


> И если да, то подскажите пожалуйста как это дело разрулить.

Способов очень много и они достаточно подробно описаны у Рихтера.
Самый простой - критические секции (TCriticalSection)


 
Leonid Troyanovsky ©   (2008-12-22 17:51) [3]


> tipman   (22.12.08 16:42)  

> да, то подскажите пожалуйста как это дело разрулить.

TThread.Synchronize, RTFM.

--
Regards, LVT.


 
tipman   (2008-12-22 20:39) [4]

Synchronize, судя по Стиву Тейксейра, синхронизирует вторичный поток с основным и служит в основном для работы с окнами, т.е. с визуальными компонентами. Механизм его ясен и это не то. Мне нужно синхронизировать вторичные потоки, и критические секции самое то...
Всем очень благодарен.


 
Sha ©   (2008-12-23 10:08) [5]


> критические секции самое то

есть еще lock-free техники (см. memory barrier)


 
Johnmen ©   (2008-12-23 20:36) [6]


> tipman   (22.12.08 16:42) 

Массив чего? И какова единица "данных"?


 
tipman   (2008-12-23 20:57) [7]

type
TMy = record
 X1: integer;
 X2: integer;
 X3: integer;
 Y1: Double;//cardinal;
 Y2: Double;//cardinal;
 Y3: Double;//cardinal;
 Y4: Double;//cardinal;
 Y5: Double;
end;

TMyMy = record
 count: integer;
 data: array of TMy;
end;
............

var
MyMy: TMyMy;

вот со структуркой MyMy типа TMyMy и надо работать параллельно в 2-х, 3-х потоках....
Вообщем то уже реализовал через критические секции, пробовал без них действительно ексесс виолайшн был :)


 
zulus5 ©   (2008-12-23 21:53) [8]

Конечно могут!!!!
Я использую такую конструкцию... очень помагает!!!

Здесь важно ALocker - это и есть решение твоей проблемы!!!
Класс от СМО с очередями где происходит передача данных от одного класса до другого в потоках! Скорость УУУх!!! 100000 - 200000 файлов за 24-30 минут по дереву обработки или сценарию.

// класс потока
Type
 TTextOrSign = class (TBaseClass) // наследуем класс от базового класса
 private
   ....
   ALocker: TMultiReadExclusiveWriteSynchronizer;
  ....

constructor TTextOrSign.Create;
begin
 Inherited Create;
 Try
  Bitmap:= TBitMap.Create;
  Bitmap.LoadFromResourceName( HInstance, "BITMAP_WEBTEXT" );
 Except end;
 ALocker:= TMultiReadExclusiveWriteSynchronizer.Create;
end;

Destructor TTextOrSign.Destroy;
begin
 if fStarted then Stop();
 ALocker.Free;
 inherited Destroy;
end;

Function TTextOrSign.SendData( iWorkData: PWorkData; frComp:Pointer):boolean;
Var FileN, err: String;
begin
 ALocker.BeginWrite;
 if Self.fWorkData^.Data = nil then GetMem(Self.fWorkData^.Data, fiData.MaxBuffSize);
 Result:= False;
 // проверка на запуск
 If Self.fStarted=False Then Exit;

 Try
 If SozdavatPotok=True then
 begin
   If TekuchixPotokov<MaxPotokov Then
   Begin
     if iWorkData^.Size > (fiData.MaxBuffSize) then
     begin
      err:= "Размер данных превышает размер буфера! (BaseClass.SendData)";
      Windows.SendMessage(fiData.MessList.WinHndl, fiData.MessList.Error, Integer(Self), Integer(err));
     end
     else
     Begin
      MoveMemory( Self.fWorkDAta^.Data, iWorkData^.Data, iWorkData^.Size);
      FileN:= PString( Self.fWorkData^.Data )^;
      Inc(TekuchixPotokov);
      FRemMulti:= TExecuteThreadTXT.Create(
                  PBaseClass(Self), FileN, DirStat,
                  VestiStatistiku, PerSoob, ZagZenit, Procent,
                  DopuskNull, Glubina_analiza, DlinaZag, ProcentProbelov );
      FRemMulti.Resume;
      Result:= True;
      Windows.SendMessage(fiData.MessList.WinHndl, fiData.MessList.Send, Integer(Self), Integer(frComp));
      Sleep(0);
     end;
   end;
  end
  else
  begin
   If inherited SendData(iWorkData, frComp) then
   Begin
    FileN:= PString( fWorkData^.Data )^;
    FileTXT( FileN, Glubina_analiza );
    Result:= True;
   end;
  end;

 Except
  Result:= False;
 end;
 ALocker.EndWrite;

end;


 
DVM ©   (2008-12-23 23:16) [9]


> zulus5 ©   (23.12.08 21:53) [8]


> ALocker: TMultiReadExclusiveWriteSynchronizer;

Хочу заметить, что TMREWS в D6 имеет ошибку, приводящуюю к взаимоблокировке потоков, поэтому использовать его можно только в более новых версиях делфи. Производительность приложения с TMREWS иногда в разы хуже, чем с критическими секциями, но есть и ситуации, где можно получить хороший выигрыш.


 
zulus5 ©   (2008-12-24 00:44) [10]

я использую D7



Страницы: 1 вся ветка

Текущий архив: 2009.12.27;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.01 c
1-1230135789
du_hast
2008-12-24 19:23
2009.12.27
Нужно получить кол-во Chart-ов в текущем Excel Sheet-е


15-1256615376
d@nger
2009-10-27 06:49
2009.12.27
Cisco и модем


4-1226246501
sqrttrqs
2008-11-09 19:01
2009.12.27
вывод изображения на печать


2-1257514920
Дмитрий Белькевич
2009-11-06 16:42
2009.12.27
I/O error 23 при чтении файла


3-1232350553
Альф
2009-01-19 10:35
2009.12.27
Как отключить кеш в IB5.6 или что это было ?