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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 21.10.2013, 16:25   #1
Unique_Maks
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 89
По умолчанию Потоки

Здравствуйте.
не выходит создать псевдопараллелизм.
Пытаюсь создать еще один поток в обработчике FormShow:
Код:
procedure TF.FormShow(Sender: TObject);
var
  p: Tmy_thread;
begin
  p := Tmy_thread.Create(true);
  p.FreeOnTerminate := true;
  p.Priority := tpNormal;
  p.Start;
  // тут процедура, выполняющаяся ~20сек
  //
  //  
  p.Terminate;
end;
наследник Tthread:

Код:
Tmy_thread = class(Tthread)
private
  form: Tform;
protected
  procedure Execute; override;
  procedure create_form;
  procedure delete_form;
end;

procedure Tmy_thread.delete_form;
begin
  form.Free;
end;

procedure Tmy_thread.Execute;
begin
  inherited;
  Synchronize(create_form);
  while not Terminated do
    sleep(50);
  Synchronize(delete_form);
end;

procedure Tmy_thread.create_form;
begin
  form := TForm.Create(F); // F - name main form
  form.Show;
end;
Все нормально работает если повесить старт и стоп потока на кнопки, а так - нет.
Подскажите в чем косяк.
Заранее благодарю.

Последний раз редактировалось Unique_Maks; 21.10.2013 в 16:30.
Unique_Maks вне форума Ответить с цитированием
Старый 21.10.2013, 17:02   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

а в чем все же ненормальность поведения приведенного кода?

в том что не показывается форма в потоке? так за показ той формы отвечает главный поток. А он занят (ему некогда)
Цитата:
// тут процедура, выполняющаяся ~20сек
//
//
а когда у него появится время, то поток уже ВСЕ
Код:
  p.Terminate;
Цитата:
если повесить старт и стоп потока на кнопки
уточним на РАЗНЫЕ кнопки (или по крайней мере на два РАЗНЫХ нажатия одной кнопки).
Так между ДВУМЯ нажатиями у главного потока найдется время и для показа всяких разных форм.

в первом (приведенном) случае вы и запуск и остановку делаете в ОДНОЙ процедуре и система не получает возможностей по отображению.
в другом (по нажатиям кнопок) запуск и остановка разнесены по разным процедурам, между которыми успевает поработать система по отображению окон(форм).
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 21.10.2013, 17:04   #3
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

А что вы сделать путаетесь? Нельзя создавать формы и т.д. не из VCL потока.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 21.10.2013, 17:09   #4
Unique_Maks
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 89
По умолчанию

Я считал, что после создания нового потока он будет работать параллельно (формально) основному и если система не загружена на 99%, то найдется время на обработку второго вместе с первым, но форма отображается, как Вы указали, на мгновение уже после долгой процедуры.
Unique_Maks вне форума Ответить с цитированием
Старый 21.10.2013, 17:12   #5
Unique_Maks
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 89
По умолчанию

Пытаюсь создать форму ожидания долгих задач
Unique_Maks вне форума Ответить с цитированием
Старый 21.10.2013, 17:26   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

Цитата:
после создания нового потока он будет работать параллельно (формально) основному
поток-то будет работать, но VCL объекты(формы) используют системные ресурсы, доступные только главному потоку. Именно поэтому и нельзя их использовать без syncronize. А доступ к системным ресурсам возможен только ВНЕ ваших процедур. Поэтому поток хоть и выполнит свою задачу по получению данных во время долгих процедур основного, но возможность показа получит только по окончании долгой процедуры основного потока.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 21.10.2013 в 17:34.
evg_m вне форума Ответить с цитированием
Старый 21.10.2013, 23:11   #7
Unique_Maks
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 89
По умолчанию

он даже не получает ни каких данных во время выполнения долгой процедуры, дальше inherited не идет, только после завершения выполнения длительной операции начинает выполнять строки после inherited.
Как поступать в таких случаях? что посоветуете?
Unique_Maks вне форума Ответить с цитированием
Старый 22.10.2013, 09:40   #8
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

procedure Tmy_thread.Execute;
begin
inherited;
Synchronize(create_form);

так сразу после inherited у вас стоит synchronize (ОЖИДАНИЕ свободного! основного потока). А он(основной поток) занят!! Вот и стоим ждем-с.
Цитата:
не получает ни каких данных во время выполнения долгой процедуры, дальше inherited не идет, только после завершения выполнения длительной операции начинает выполнять строки
Надо убирать из-потока Synchornize.

алгоритм работы таков (должен быть).
в основном потоке
1.создаем поток в остановленном состоянии
2.готовим данные (в т.ч. создаем показываем форму ожидания)
3.ПИШЕМ процедуру и задаем потоку OnTerminate (что делать когда поток закончит работу) например убрать форму!! примеры есть на форуме.
4.запускаем поток. В нем теперь нет ни одной Synchronize (мы их оставили в основной программе.
Да и форма ему не нужна. Наоборот это форма которую мы показываем знает про поток и что ей делать когда поток остановится и как его остановить.

Код:
Tform1 =class(TFrom)
private
  mythread: TTread; // знает про СВОЙ поток.

procedure OnTreadTerminate(sender: TObject); // что делать когда поток остановится

procedure ButtonStopClick(sender: TObject); //как его остановить
P.S. и никаких долгих процедур в основном потоке. иначе ЛЮБОЙ показ будет только после.
точнее любой syncronize потока будет ждать любую "долгую" процедуру основного потока.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 22.10.2013 в 09:54.
evg_m вне форума Ответить с цитированием
Старый 22.10.2013, 13:11   #9
Unique_Maks
Пользователь
 
Регистрация: 07.06.2010
Сообщений: 89
По умолчанию

то же самое что и
Код:
procedure Tmain_form.FormShow(Sender: TObject);
var
  form: Tform;
begin
  form := Tform.create(main_form);
  form.show;
  // долгая задача
  //
  form.free
end;

Последний раз редактировалось Unique_Maks; 22.10.2013 в 13:13.
Unique_Maks вне форума Ответить с цитированием
Старый 22.10.2013, 13:45   #10
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

Цитата:
// долгая задача
//
А вот этому самое место в потоке!
Создали форму, поток, и сидим плюем в потолок пока он трудится. А форма ничего не делает. Только разве что следит за потоком
Код:
Trrad.OnTerminate:=formx.TreadStoped; //при остановке форма получит "извещение" (в основном потоке будет вызвана указанная процедура).
И при желании может остановить его же
Код:
Trrad.Terminate;
программа — запись алгоритма на языке понятном транслятору

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


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Потоки с++ Алена_=))) Помощь студентам 0 26.12.2011 16:12
потоки AlexMe Общие вопросы Delphi 3 18.07.2011 05:17
Потоки. FieStik Общие вопросы C/C++ 4 23.05.2011 14:12
Потоки Aleksey1989 Помощь студентам 2 27.10.2010 10:07
потоки Владимир1988 Помощь студентам 0 08.02.2010 23:12