Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.09.2010, 18:21   #1
SkrudjMakdak
Форумчанин
 
Регистрация: 14.04.2010
Сообщений: 145
По умолчанию Потоки - Как сделать чтоб не предок ждал пока наследники подсчитают, а один наследник ждал другого?

Может кто нибудь подсказать\рассказать про потоки. Я взял пример из книги: Фленов М "Библия Delphi", немного изменил:

Цитата:
unit Main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, MyThread;

type
TForm1 = class(TForm)
RichEdit1: TRichEdit;
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
co: array [0..1] of TCountObj;
public
{ Public declarations }
end;

var
Form1: TForm1;
k: word;
implementation


{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
for k:=0 to 1 do
begin
co[k]:=TCountObj.Create(true);
co[k].FreeOnTerminate:=true;
co[k].Resume;
co[k].Priority:=tpLower;
end;
WaitForMultipleObjects(2, @co, true, infinite);
ShowMessage('asd');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
co[0].Terminate;
co[1].Terminate;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
co[0].Terminate;
co[1].Terminate;
end;

end.


Цитата:
unit MyThread;

interface

uses
Classes, Sysutils, Windows, Messages;

type
TCountObj = class(TThread)
private
{ Private declarations }
index:Integer;
protected
procedure Execute; override;
constructor Create();
public
event: THandle;
end;

implementation

uses Main;

{ TCountObj }

constructor TCountObj.Create;
begin
event := CreateEvent(nil, true, false, '');
ResetEvent(event);
end;

procedure TCountObj.Execute;
begin
index:=1;
while index>0 do
begin
Inc(index);
if index>300000 then
Terminate;

if index=200000 then
SetEvent(event);

SendMessage(Form1.Edit1.Handle, WM_SETTEXT, 0, Integer(PChar(IntToStr(index))));

if terminated then exit;
end;
end;

end.
И у меня несколько вопросов:
Поидеи он должен досчитывать до 200000 и выдавать сообщение: "asd"? но не получается, почему?

Как сделать чтоб не предок ждал пока наследники подсчитают, а один наследник ждал другого наследника??? (и если их больше двух)

Как сделать чтоб один поток выводил полученые результаты в один Edit, а второй поток в другой Edit? (Я понимаю что 2 потока выводят index в один Edit)
SkrudjMakdak вне форума Ответить с цитированием
Старый 20.09.2010, 18:53   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

а вы что ждете то?
надо ждать по TThread.Handle , а не по адресу обьекта.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 20.09.2010, 19:12   #3
SkrudjMakdak
Форумчанин
 
Регистрация: 14.04.2010
Сообщений: 145
По умолчанию

Тогда я вообще ничего не пойму. В каком юните писать функцию писать нужно(WaitForMultipleObjects(2, @co, true, infinite)? можно примерчик???
SkrudjMakdak вне форума Ответить с цитированием
Старый 20.09.2010, 19:19   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Код:
var H:array[0..1] of THandle;
begin
for k:=0 to 1 do
 begin
  co[k]:=TCountObj.Create(true);
  co[k].FreeOnTerminate:=true;
  co[k].Resume;
  co[k].Priority:=tpLower;
  H[k]:=cp[k].Handle;
 end;
 WaitForMultipleObjects(2,@H[0], true, infinite);
 ShowMessage('asd');
end;
сомневаю что вы видели пример такой/подобный же как вы написали.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 20.09.2010, 19:58   #5
SkrudjMakdak
Форумчанин
 
Регистрация: 14.04.2010
Сообщений: 145
По умолчанию

Разницы я что то не увидел. точнее вообще никаких действий и комп не реагирует, а проц показывает что не загруженный

Я понял. Дело в тупике:
SendMessage(Form1.Edit1.Handle, WM_SETTEXT, 0, Integer(PChar(IntToStr(index))));
2 потока обращается одновременно в Edit1, а вот как исправить не знаю

Последний раз редактировалось Stilet; 21.09.2010 в 14:47.
SkrudjMakdak вне форума Ответить с цитированием
Старый 21.09.2010, 14:41   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
SendMessage(Form1.Edit1.Handle, WM_SETTEXT, 0, Integer(PChar(IntToStr(index))));
2 потока обращается одновременно в Edit1, а вот как исправить не знаю
поток должен занть куда он пишет, иметь соответствующее поле.
в классе потока вводим новое поле
mshandle: HWnd;

задаем ДО запуска, но после создания потока ему нужные значения
кому form1.edit1.handle кому form1.edit2.Handle

меняем вызов
SendMessage(mshandle, WM_SETTEXT, 0, Integer(PChar(IntToStr(index))));
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 21.09.2010 в 14:46.
evg_m вне форума Ответить с цитированием
Старый 21.09.2010, 19:12   #7
SkrudjMakdak
Форумчанин
 
Регистрация: 14.04.2010
Сообщений: 145
По умолчанию

А можно примерчик, я что то не догоняю
SkrudjMakdak вне форума Ответить с цитированием
Старый 22.09.2010, 09:03   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

поток должен знать куда он пишет, иметь соответствующее поле.
в классе потока вводим новое поле
type TmyThead=class(....)
private
mshandle: HWnd;
......
end;

задаем ДО запуска, но после создания потока ему нужные значения
кому form1.edit1.handle кому form1.edit2.Handle
th1:=TmyThead.Create;
th1.mshandle:=form1.edit2.handle;

th2:=TmyThead.Create;
th2.mshandle:=form1.edit1.handle;



меняем вызов
SendMessage(Form1.Edit1.Handle, WM_SETTEXT, 0, Integer(PChar(IntToStr(index))));
на такой
SendMessage(self.mshandle, WM_SETTEXT, 0, Integer(PChar(IntToStr(index))));
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 22.09.2010 в 09:09.
evg_m вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сделать чтоб listbox показывал нумерацию? blackstersl Общие вопросы Delphi 7 01.02.2009 14:28
Как вычесть один диапазон из другого? viter.alex Microsoft Office Excel 11 20.01.2009 16:30
Как сделать, чтоб в ячейке ВЫБИРАЛОСЬ? kristinafadeewa Microsoft Office Excel 12 27.10.2008 06:05
как сделать чтоб экселев. файл висел открытым на рабочем столе как афиша на заборе? Мара Помощь студентам 6 24.07.2008 13:29
Как сделать чтоб картинки менялись? Kaktys v tymane Помощь студентам 1 09.05.2008 00:53