Форум: "Начинающим";
Текущий архив: 2014.04.27;
Скачать: [xml.tar.bz2];
Внизaccess violation при работе с потоками Найти похожие ветки
← →
Valdis (2013-07-17 19:18) [0]Я тренируюсь работать с потоками для параллельных вычислений и столкнулся со следующей проблемой. Это просто пример:
Необходимо создать два потока, которые берут массив из основной части программы, делуют некие преобразования над его элементами и возвращают эти преобразованные элементы обратно в программу:unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Memo1:TMemo;
Button1:TButton;
procedure Button1Click(Sender:TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TStrAr = array[1..10]of integer;
TCalcThread = class(TThread)
private
FIsDone:Boolean;
FA,FB:TStrAr;
public
constructor Create(A:TStrAr); virtual;
property IsDone:Boolean read FIsDone;
property A:TStrAr read FA;
property B:TStrAr read FB;
end;
T1st = class(TCalcThread)
private
protected
procedure Execute; override;
end;
T2nd = class(TCalcThread)
private
protected
procedure Execute; override;
end;
var Form1:TForm1;
implementation
{$R *.dfm}
constructor TCalcThread.Create(A:TStrAr);
begin
inherited Create(False);
FA:=A; FIsDone:=False end;
procedure T1st.Execute;
var i:integer;
begin for i:=1 to 10 do FB[i]:=FA[i]+1; FIsDone:=True end;
procedure T2nd.Execute;
var i:integer;
begin for i:=1 to 10 do FB[i]:=sqr(FA[i]); FIsDone:=True end;
procedure TForm1.Button1Click(Sender:TObject);
var t1,t2:TCalcThread; m:TStrAr; i:integer;
begin
for i:=1 to 10 do m[i]:=2*i;
t1:=T1st.Create(m); t2:=T2nd.Create(m);
While True Do Begin
If t1.IsDone And t2.IsDone Then Begin
for i:=1 to 10 do begin
Memo1.Lines.Add(inttostr(t1.B[i])); Memo1.Lines.Add(inttostr(t2.B[i])) end;
FreeAndNil(t1); FreeAndNil(t2) End; Sleep(200) End
end;
end.
После компиляции выскакивает access violation. Почему это происходит? Помогите найти ошибку в коде. Спасибо
← →
RWolf © (2013-07-17 19:24) [1]inherited Create(False); //запустил поток прежде, чем запомнил аргументы.
← →
Valdis (2013-07-17 19:30) [2]А как правильно? Я поставил его в конец и все равно access violation
← →
MBo © (2013-07-17 19:50) [3]в цикле While True уничтожаются потоки, но он продолжается.
Это можно было заметить при отладке.
← →
Valdis (2013-07-17 20:09) [4]А как правильно уничтожить потоки. Как это исправить?
← →
MBo © (2013-07-17 20:34) [5]цикл надо прервать- break или проверку условия добавить
← →
Valdis (2013-07-17 20:38) [6]Уважаемый MBo подскажите (на коде) как правильно. У меня с тредами проблемы. И ещё насчёт сообщения от RWolf про inherit?
← →
MBo © (2013-07-17 20:45) [7]>У меня с тредами проблемы
Эта проблема не с тредами, а с логикой цикла. Как поправить - я подсказал
← →
sniknik © (2013-07-17 21:39) [8]> И ещё насчёт сообщения от RWolf про inherit?
он имеет в виду что "рабочая процедура" - execute начинает выполнятся после создания (если не параметр "приостановлено"), а у тебя вызов родительского create до того как инициализировал параметры используемые в execute...
хотя... так ли это важно если сам create у тебя виртуальный? есть ли у него "родитель"? :)
p.s. в дельфе есть хороший пример на потоки... папка Demos\Threads.
← →
Anatoly Podgoretsky © (2013-07-17 21:43) [9]Надо использовать синхронизацию (synhronize)
← →
Valdis (2013-07-17 22:11) [10]@ sniknik В начале создаем (create), а потом выполняем (execute) разве не такая логика? Я читал что inherited create нужен в constructor, а не в execute. Или вы имеете в виду что нужно удалить (False) и просто оставить inherited Create?
Папка демо пустая наверно надо переустановить. Примеров много, но толковые найти нелегко.
@ Anatoly Podgoretsky А что здесь синхронизировать? Потоки независимы друг от друга и не перекрываются.
← →
Cobalt © (2013-07-17 22:28) [11]Valdis
А теперь посмотри, что за параметр в конструкторе создания TThread
← →
Valdis (2013-07-17 22:56) [12]@ Cobalt
в конструкторе создания TCalcThread параметр - массив, который будет браться из главной программы. А что там еще должно быть?
← →
Cobalt © (2013-07-17 23:16) [13]Рекомендую обратить внимание на конструктор именно класса TThread, коий ты вызываешь с некоторым аргументом.
← →
Valdis (2013-07-17 23:55) [14]@ Cobalt
Аргументов всего три. Один массив исходных данных, второй это преобразованный массив (a -> b), который выдают потоки, и третий это логическая переменная которая говорит о завершении потока. Если что-то неверно покажите на коде, ато я так не догоняю. Если мне все было понятно, то я не спросил бы.
Мне просто нужно провести параллельные вычисления, каждый поток получает, обрабатывает и возвращает. Это сложный процесс? Или код просто будет длинным? Я понимаю принцип, но никак не могу это правильно реализовать. Практики с классами и тредами у меня мало и никто не хочет доходчиво объяснить.
← →
MBo © (2013-07-18 06:00) [15]
While True Do Begin
If t1.IsDone And t2.IsDone Then Begin
for i:=1 to 10 do begin
Memo1.Lines.Add(inttostr(t1.B[i]));
Memo1.Lines.Add(inttostr(t2.B[i]))
end;
FreeAndNil(t1);
FreeAndNil(t2);
Break;
End;
Sleep(200);
End
← →
icWasya © (2013-07-18 09:24) [16]Valdis, внимательно смотри, о чём тебя Cobalt спрашивает в
(17.07.13 22:28) [11]
(17.07.13 23:16) [13]constructor TCalcThread.Create(A:TStrAr);
begin
inherited Create(False); /// <<===--- вот здесь ты вызываешь Thread.Create
Читай справку, что означает этот параметр
← →
Valdis (2013-07-18 12:06) [17]Всем спасибо, разобрался
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2014.04.27;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.002 c