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

Вниз

Ошибка доступа при работе с потоками/нитями   Найти похожие ветки 

 
Tkach_   (2002-06-13 13:36) [0]

Столкнулся с проблемой при работе с потоками.
Поток А запускает поток В. Код выглядит следующим образом:

procedure TAThread.Execute;
begin
while not Terminated do
begin
Synchronize(UpdateLog);
if StartBFlag then
BList.Add(TBThread.Create(False));
end;
end;

procedure TBThread.Execute;
begin
while not Terminated do
Synchronize(UpdateLog);
end;

В результате генерируется ошибка: "access violation at <adress1>: write of adress <adress2>"

Помогите разобраться.


 
Игорь Шевченко ©   (2002-06-13 13:37) [1]

Что делает UpdateLog ?


 
Digitman ©   (2002-06-13 13:44) [2]

<adress1> , <adress2> - это для тебя диагностика, а не для Пушкина)


Значение <adress1> совместно с меню "Search|Find Error.." главного окна IDE Делфи, запустившего приложение врежиме встроенной отладки, укажет тебе модуль и строку в нем, при выполнении которой произошло AV


 
Tkach_   (2002-06-13 14:10) [3]

2 Игорь Шевченко ©
UpdateLog обоих потоков обновляет Мемо главной формы и устанавливает флаг StartBFlag (только поток А)


 
Игорь Шевченко ©   (2002-06-13 14:12) [4]

Э...код бы...


 
Tkach_   (2002-06-13 14:35) [5]

код такой

procedure TАThread.UpdateLog;
begin
MainForm.Memo1.Lines.Add("что-то там");
StartBFlag:=(MainForm.Name1=Self.Name1);
end;

procedure TBThread.UpdateLog;
begin
MainForm.Memo1.Lines.Add("что-то там");
end;


 
Внук ©   (2002-06-13 14:38) [6]

Переполнение Memo?


 
Fiend ©   (2002-06-13 14:44) [7]

Я думаю что дело в возможности одновременного выполнения MainForm.Memo1.Lines.Add("что-то там");
разными потоками. Synchronyze насколько я знаю синхронизит поток с главным потоком приложения и то что вы в обоих потока А и Б делаете это не защизает Вас от одновременного выполнения метода АДД объекта Lines. А если один поток А вызвал этот метод но он не успел завершиться и тут вдруг проц переключился на выполнение другого потока Б, который тоже вдруг в этот момент вызвал тот же метод - сечете к чему это может привести???
Вам нужно использовать разделение ресурсов между потоками, это нада сделать при помощи Мьютексов или семафоров или т.д. что больше подходит

Ошибка может происходить в принципе не только из за метода АДД, мы ведь здесь весь код не видим


 
Tkach_   (2002-06-13 14:48) [8]

с мемо все в порядке. Ошибка выдается при первом вызове Synchronize(UpdateLog) в потоке В:

procedure TBThread.Execute;
begin
while not Terminated do
Synchronize(UpdateLog); // здесь ОШИБКА AV!!!
end;




 
Внук ©   (2002-06-13 14:50) [9]

>>Fiend © (13.06.02 14:44) "Synchronyze насколько я знаю синхронизит поток с главным потоком приложения" - вот именно, поэтому описываемая Вами ситуация здесь невозможна. Иначе, что Вы понимаете под словом "синхронизирует"?


 
Fiend ©   (2002-06-13 14:56) [10]

то что поток А например (вызвавший Synch) будет ждать завершения вызываемой процедуры.
Но второй то поток в это время не дремлет и тоже может вызвать Synchronyze(таже функция)
Поверьте, я вам дело говорю, у меня тоже были подобные проблемы с разделением ресурсов разными потоками одного приложения. Пока не начитался умных книжек про это дело и не стал юзать для разделения специальные классы, такие глюки были и я тоже не просекал в чём дело


 
Игорь Шевченко ©   (2002-06-13 14:56) [11]

Код UpdateLog в студию


 
Внук ©   (2002-06-13 14:59) [12]

BList тоже небезразмерный. Вообще этот код приведет к быстрому перерасходу памяти :) А то, что ошибка вылетает на той строке - так получилось :) Попробуйте ограничить выполнение каждого цикла хотя бы 10 итерациями и посмотрите, что получится.


 
Fiend ©   (2002-06-13 14:59) [13]

ааааахахахаххаа, и побольше доктор! ПОБОЛЬШЕ кода!!!!


 
Внук ©   (2002-06-13 15:01) [14]

>>Fiend © (13.06.02 14:56)
Это может привести максимум к DeadLock, то есть обыкновенному повисанию приложения, но никак не к AV


 
Внук ©   (2002-06-13 15:03) [15]

Но здесь и этого не будет, поскольку синхронизируются всего лишь UpdateLog - очень нехитрые процедуры


 
Fiend ©   (2002-06-13 15:05) [16]

Я так думаю, что столь уважаемая АВ является причиной некорректного или несанкционированного системой совместного доступа к памяти, вполне возможно и из двух потоков


 
Игорь Шевченко ©   (2002-06-13 15:09) [17]

Memo1 надо защищать критической секцией.

Рихтера учить наизусть, главу про синхронизацию потоков


 
kull ©   (2002-06-13 15:14) [18]

2Friend
Syncronize использует виндовскиую очередь сообщений для синхронизации так что одновременно вызваться метод Add из разных мест не может. Очевидно причина ваших глюков была в другом и похоже ваша проблемма решена не в правильном направлении.


 
Внук ©   (2002-06-13 15:15) [19]

Народ, ну фактически здесь происходит в самом худшем случае
Syncronize(MainForm.Memo1.Lines.Add("что-то там")); - из потока А
Syncronize(MainForm.Memo1.Lines.Add("что-то там")); - из потока B
Оба вызова встраиваются в контекст главного потока, и все нормально живет. Иначе зачем нужен Syncronize???



 
Игорь Шевченко ©   (2002-06-13 15:19) [20]

Внук © (13.06.02 15:15)

Похоже, я притормозил :-)


 
Внук ©   (2002-06-13 15:22) [21]

>>Игорь Шевченко © (13.06.02 15:19)
Надо дождаться, что автор ответит на Внук © (13.06.02 14:59), тогда видно будет :)


 
Fiend ©   (2002-06-13 15:27) [22]

2kull
Ну для начала мой ник всё же FIEND а не FRIEND!!!
Ну а второе - моя проблема как раз правильно решена
А третье - автору то самому уже помоему уже ничего и не надо, он сам ничё не отвечает и не спрашивает


 
Игорь Шевченко ©   (2002-06-13 15:29) [23]

Автору: Я воспроизвел код - ошибки нет. D5/NT4


 
kull ©   (2002-06-13 15:37) [24]


> Fiend © (13.06.02 15:27)

Ну за ник прошу прощения - очепятка вышла.
А насчет автора - так я-же не ради автора а ради дела...



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

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

Наверх




Память: 0.52 MB
Время: 0.017 c
14-77599
kaif
2002-05-22 11:11
2002.06.24
Мне пришло 2 авиабилета FREE


1-77415
кондратий
2002-06-10 18:21
2002.06.24
мышь и скролинг ...


1-77377
Maikl
2002-06-10 16:28
2002.06.24
Определить формат файлов


1-77406
Big Daddy
2002-06-13 21:09
2002.06.24
Поменять движения мышки


1-77414
Гаргоша
2002-06-11 01:51
2002.06.24
Объединение ячеек таблицы в WORD