Форум: "Основная";
Текущий архив: 2009.12.27;
Скачать: [xml.tar.bz2];
ВнизИспользование общих переменных в различных потоках Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.006 c