Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Ошибка доступа при работе с потоками/нитями [D5, Win95/98, WinME, NT4, Win2k, WinXP]


Страницы:   1 2

Tkach_ ©   (2002-06-13 13:36:00) 

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

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>"

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


kull   (2002-06-13 15:37:00) [1]


> Fiend © (13.06.02 15:27)

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


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

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


Fiend   (2002-06-13 15:27:00) [3]

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


Внук   (2002-06-13 15:22:00) [4]

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


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

Внук © (13.06.02 15:15)

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


Внук   (2002-06-13 15:15:00) [6]

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


kull   (2002-06-13 15:14:00) [7]

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


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

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

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


Fiend   (2002-06-13 15:05:00) [9]

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


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

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


Внук   (2002-06-13 15:01:00) [11]

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


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

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


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

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


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

Код UpdateLog в студию


Fiend   (2002-06-13 14:56:00) [15]

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


Внук   (2002-06-13 14:50:00) [16]

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


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

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

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



Fiend   (2002-06-13 14:44:00) [18]

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

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


Внук   (2002-06-13 14:38:00) [19]

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


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

код такой

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

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо