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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 24.11.2010, 11:14   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию TThread выполняет что-либо пока работает запущенная им программа

Всем привет!
Вернусь к вам со своим бараном=)

Собственно:
поток TThread запускает програму используя функцию CreateProcess и ждёт когда та отживёт своё:
Код:
WaitForSingleObject(ProcessInform.hprocess,Inifinite);
Проблема:
Изменить работу потока таким образом, чтобы пака работает программа поток что-то выполнял. К примеру: Сверял время с системным, и завершил программу в указанное время, а затем и сам закрылся.

Собственно перечитал много чего=) Много где советовали использовать результаты WaitForSingleObject. Делаю:
Код:
procedure TTThread.Execute;
var
  Reasson: DWORD;
  PrcI: TProcessInformation;
  SI: TStartupInfo;

begin
  ZeroMemory(@SI, SizeOf(SI));
  Si.cb := SizeOf(SI);
  CreateProcess(PAnsiChar(MainForm.AppEdit.Text), nil, nil, nil, False, 0, nil, nil, SI, PrcI);
  repeat
    Reasson := WaitForSingleObject(PrcI.hProcess, 100);
    if Reasson = WAIT_OBJECT_0 then
    begin
      if TimeToStr(Now) = MainForm.TimeEdit.Text then
      begin
        TerminateProcess(PrcI.dwProcessId, 0);
        Break;
        Terminate;
      end;
    end;
  until Reasson <> Wait_TIMEOUT;
end;
Но результата НОЛЬ.
Может время не привельно сверяю? Может ещё что-то?

Нарвался на статью "Синхронизация процессов при работе с Windows (статья)" в DRKB прочитал и перечитал, и понял что я чего-то не понимаю, а именно "Что такое сигнальное состояние?".

Выкладываю проект, может там ошибка..

Вложения
Тип файла: zip TimerInThread.zip (2.4 Кб, 9 просмотров)

Последний раз редактировалось Человек_Борща; 24.11.2010 в 11:19.
Человек_Борща вне форума Ответить с цитированием
Старый 24.11.2010, 21:12   #2
wm_leviathan
Форумчанин
 
Аватар для wm_leviathan
 
Регистрация: 17.02.2010
Сообщений: 399
По умолчанию

примерно так
Код:
procedure TMainForm.Something;
begin
Form1.Edit1.Text:= InttoStr(Answer);
CopyFile('c:\3\123.exe', 'd:\1\123.exe');
end;
//------
procedure TThreadCopy.Execute;
var
begin
CopyFile(mainForm.Source+'\'+ThreadMonFile.NewF , mainForm.Dest+'\'+ThreadMonFile.NewF);
Synchronize(MainForm.Something);
end;
Цитата:
Проблема:
Изменить работу потока таким образом, чтобы пака работает программа поток что-то выполнял. К примеру: Сверял время с системным, и завершил программу в указанное время, а затем и сам закрылся.
Пока работает программа поток и так выполняет а именно он то запускает и следит за запущенной прогой. тогда вам надо чтобы не поток запускал и следил а сама программа. либо пусть тогда поток запускает а программа в это время следит. чуть чуть изменил ваш пример:
поток открывает и следит в то время как главная форма делает ShowMessage.
почему то не дает сделать вложение

Код:
procedure TMainForm.LaunchBtnClick(Sender: TObject);
begin
  Thr := TTThread.Create(True);
  Thr.FreeOnTerminate := True;
  Thr.Priority := tpNormal;
  Thr.Resume;
  hello;
end;
procedure TMainForm.Hello;
var i:integer;
begin
  for i:=0 to 15 do
  showmessage('Привет');
end;

Последний раз редактировалось Stilet; 25.11.2010 в 11:09.
wm_leviathan вне форума Ответить с цитированием
Старый 24.11.2010, 22:07   #3
maxionans
Форумчанин
 
Аватар для maxionans
 
Регистрация: 02.01.2010
Сообщений: 254
По умолчанию

Ты напутал с обработкой значений, возвращаемых функцией WaitForSingleObject. Вот так будет правильно:

Код:
procedure TTThread.Execute;
var
  Reasson: DWORD;
  PrcI: TProcessInformation;
  SI: TStartupInfo;

begin
  ZeroMemory(@SI, SizeOf(SI));
  Si.cb := SizeOf(SI);
  CreateProcess(PAnsiChar(MainForm.AppEdit.Text), nil, nil, nil, False, 0, nil, nil, SI, PrcI);
  repeat
    Reasson := WaitForSingleObject(PrcI.hProcess, 100);
    if Reasson = WAIT_TIMEOUT then
    begin
      if TimeToStr(Now) = MainForm.TimeEdit.Text then
      begin
        TerminateProcess(PrcI.dwProcessId, 0);
        Break;
        Terminate; <<< это зачем? код в теле цикла после Break не выполняется  
      end;
    end;
  until Reasson <> WAIT_TIMEOUT;
end;
Жирным отмечены места, на которые следует обратить внимание.
maxionans вне форума Ответить с цитированием
Старый 25.11.2010, 01:24   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Мне необходимо чтобы поток запускал и ждал завершения того что запустил. А пока он ждёт завершения то, он сверяет системное время с заданным, и в заданное время он убивает то что запустил.

maxionans
Попровал согласно вашему замечанию.

Но :
Код:
      if TimeToStr(Now) = MainForm.TimeEdit.Text then
      begin
        TerminateProcess(PrcI.dwProcessId, 0);
        Break;
      end;
не сработатывает. Почему?
Человек_Борща вне форума Ответить с цитированием
Старый 25.11.2010, 06:29   #5
maxionans
Форумчанин
 
Аватар для maxionans
 
Регистрация: 02.01.2010
Сообщений: 254
По умолчанию

для начала нужно проверить, входит ли выполнение кода в условное ветвление "if Reasson = WAIT_TIMEOUT then". Если входит, тогда искать проблему в сравнении "TimeToStr(Now) = MainForm.TimeEdit.Text". Вообще, лучше TimeEdit заменить на TDateTimePicker и сравнивать как "if CompareTime( Now, DateTimePicker.Time ) >= 0 then".
maxionans вне форума Ответить с цитированием
Старый 25.11.2010, 11:02   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

условие
Код:
if Reasson = WAIT_TIMEOUT then
Проходит.
Далее если указанное время уже прошло или сейчас есть. То прыгает в :
Код:
TerminateProcess(PrcI.dwProcessId, 0);
Затем на Break.
Затем END; тела TThread.execute;
Потом идёт в:
Код:
function GetCurrentThreadId; external kernel32 name 'GetCurrentThreadId';
Затем, через пару прыжков по Windows.pas:
Код:
function WaitForSingleObject; external kernel32 name 'WaitForSingleObject';
Затем лезет в класс Tthread и пытвается уничтожить поток зная что
TmyThread.FreeOnTerminate:=TRUE;

Затем AccessViolation с обращением к нулям.

И всё при условии что TerminateProcess так и небыло выполнено! Запущенная программа продолжает работать!

Я в недоумении...
Человек_Борща вне форума Ответить с цитированием
Старый 25.11.2010, 11:42   #7
maxionans
Форумчанин
 
Аватар для maxionans
 
Регистрация: 02.01.2010
Сообщений: 254
По умолчанию

У тебя в TerminateProcess передаётся идентификатор процесса, но туда нужен его хендл: TerminateProcess( PrcI.hProcess ). И не забудь закрывать хендлы процесса перед выходом из потока: CloseHandle( PrcI.hProcess ) и CloseHandle( PrcI.hThread ). А с Access Violation отдельно разбираться надо.
maxionans вне форума Ответить с цитированием
Старый 25.11.2010, 13:23   #8
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Ура, работает!
Код:
procedure TTThread.Execute;
var
  Reasson: DWORD;
  PrcI: TProcessInformation;
  SI: TStartupInfo;

begin
  ZeroMemory(@SI, SizeOf(SI));
  Si.cb := SizeOf(SI);
  CreateProcess(PAnsiChar(MainForm.AppEdit.Text), nil, nil, nil, False, 0, nil, nil, SI, PrcI);
  repeat
    Reasson := WaitForSingleObject(PrcI.hProcess, 100);
     if Reasson = WAIT_TIMEOUT then
    begin
      if CompareTime(Now, MainForm.TimeEdit.Time ) >= 0 then
      begin
        TerminateProcess(PrcI.hProcess, 0);
        CloseHandle(PrcI.hProcess);
        CloseHandle(PrcI.hThread);
        Break;
      end;
    end;
  until Reasson <> Wait_TIMEOUT;
end;
Вопрос решён!
maxionans отдельное большое спасибо и +
Человек_Борща вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Написать сообщение (Ассемблер )Написать комментарии и определить что выполняет TSR программа 9ino4ka Помощь студентам 3 02.06.2010 16:57
Как работает программа и что делает dragun4ik Помощь студентам 0 23.05.2010 15:51
Не работает программа, что делать? St1mkA Помощь студентам 6 28.04.2010 20:22
Определить что выполняет данная программа anna_ Помощь студентам 2 17.12.2009 22:03
что выполняет код sanya_oz Общие вопросы Delphi 2 23.04.2009 12:02