Threadы, м..ть их!!! Помогите.

  • Автор темы Neubcoder
  • Дата начала
Статус
Закрыто для дальнейших ответов.
N

Neubcoder

#1
3 потока вызываемые один в момент выполнения другого. Почему выолняются последовательно (начиная от последнего запущенного) а не одновременно. В чём ошибка?

ВОТ КОД:

type
shit = class(TThread)
private
d:Tidhttp;
protected
procedure execute;override;
procedure dofack;
end;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
IdHTTP1: TIdHTTP;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure s1;
procedure s2;
procedure s3;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
threadvar who:byte;
w1,w2,w3:integer;


implementation

{$R *.dfm}

procedure shit.execute;

begin
synchronize(dofack);
end;

procedure shit.dofack;
var cycle:integer;
begin

for cycle:=1 to 15000 do begin
if who=1 then begin w1:=cycle;synchronize(form1.s1);end else
if who=2 then begin w2:=cycle;synchronize(form1.s2);end else
if who=3 then begin w3:=cycle;synchronize(form1.s3);end;
end;
end;

procedure tform1.s1;
begin
application.ProcessMessages;
form1.Button1.Caption:=inttostr(w1);
end;

procedure tform1.s2;
begin
application.ProcessMessages;
form1.Button2.Caption:=inttostr(w2);
end;

procedure tform1.s3;
begin
application.ProcessMessages;
form1.Button3.Caption:=inttostr(w3);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin

who:=1;
shit.Create(false);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin

who:=2;
shit.Create(false);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin

who:=3;
shit.Create(false);
end;
 
Y

Yason

#2
Мда, дружище-бобёр... © B)

И где у тебя, скажи пожалуйста, задуманы ТРИ одновременно работающих потока?

В данном случае у тебя при нажатии на кнопку формы создаётся один поток, который, вместо того, чтобы в стороне от интерфейса заняться какими-то своими делами, быстренько вызывает dofack в основном потоке приложения (synchronize - выполнение в основном потоке приложения), таким образом теряется весь смысл создания этого потока, т.к. работа ведётся всё равно в основном.

Но благодаря наличию application.ProcessMessages, интерфейс всё же реагирует на пользователя. Когда ты нажимаешь другую кнопку, у тебя создаётся ещё один экземпляр потока, который опять-таки быстренько переходит к выполнению doshit в контексте основного потока. В это время поток, созданный нажатием первой кнопки, ждёт когда же ему вернётся управление из Application.ProcessMessages. B)
(Кстати, в правильном многопоточном приложении в общем случае не должно быть никаких application.ProcessMessages.)

Но всё-таки, немного конструктивности:
Код:
procedure shit.execute;
begin
synchronize(dofack);
end;
наверняка будет полезно заменить хотя бы на
Код:
procedure shit.execute;
begin
dofack;
end;
Тем самым, управление в основной поток прилоежния будет передаваться только для обновления интерфейса, что есть правильно.

PS Поищи какую-нибудь многопоточную прогу, помедитируй над исходниками. Мне в своё время очень помогло...
 
Статус
Закрыто для дальнейших ответов.