Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Проблемма с потоком


Автор: Tronix 15.10.2009, 15:31
Всем привет.
Наверное вопрос дурацкий, но к сожалению в просмотренных мной темах по потокам в поиске ответа не нашел. Сам я в дельфи новичок,  не бейте сильно.

Ситуация такая: нужно стартовать поток, потом либо полностью его убить/либо заморозить, и потом создать/стартовать заново.
Процедура, которая вызывается из главной формы по нажатию допустим кнопки старт:
Код

Procedure Emulate(b:byte);
var
  NewThread: TNewThread;
begin
  If b = 0 then  // создаем новый поток, только один раз допустим при старте программы
  begin
  NewThread:=TNewThread.Create(true);
  NewThread.FreeOnTerminate:=true;
  NewThread.Priority:=tpLower;
  NewThread.Resume;
  end else
  if b = 1 then  // хочу остановить поток на время
  begin
  NewThread.Suspend;
  end else  // и если b=2 продолжить выполнение
    NewThread.Resume;
End;


Сама процедура потока. Впринципе ничего интересного:
Код

Procedure TNewThread.Execute;
Begin
While not Terminated do
begin
//    If canrun then
//    begin
    GetOpcode;
    if delay_timer > 0 then Dec(delay_timer);
    if sound_timer > 0 then Dec(sound_timer);
    ExecuteOpcode;
    sleep(1);
//    end;
end;
end;


Так вот, поток нормально стартует, но при желании его заморозить вываливается по ексепшену неверный дескриптор на процедуре  NewThread.Suspend;
Пробовал делать через флаг canrun - из основной программы устанавливаю его в false, чтобы программно заморозить поток, но иногда видимо поток опережает определение флага и проскакивает его.
Помогите пожалуйста сделать нормальную остановку и запуск потока. Если уж не с заморозкой, то хотябы подскажите как полностью прибить поток и пересоздать его заного.? Если нужно больше кода или что-то невнятно обьяснил, спросите, я дам больше информации. Извиняюсь за сумбурное изложение, мозг уже плавится, всю ночь и пол дня пытался завести, не получается.
Заранее спасибо.

Автор: kami 15.10.2009, 17:12
Цитата(Tronix @  15.10.2009,  15:31 Найти цитируемый пост)
Процедура, которая вызывается из главной формы по нажатию допустим кнопки старт:

Убрать 
Код

NewThread: TNewThread;

\из процедруы кнопки и поставить его в private (или любую другую) секцию формы. Дело в том, что NewThread при первом нажатии на кнопку <> NewThread при последующих, по выходу из процедуры все переменные, обхявленные в этой процедуре "локально" просто забываются и при новом вызове процедуры в них содержится ерунда, никоим боком не относящаяся к тому, что в них было ранее.

Добавлено через 5 минут и 33 секунды
И не забыть в OnDestroy формы (или где-там-предусмотрено-логикой-программы) уничтожить поток. Навскидку - использование FreeOnTerminate=True чревато тем, что поток может оказаться уничтоженным, а вот ссылка на него (т.е. переменная newThread) обнулена не будет. Если обратиться к этому потоку после его прерывания, то можн будет схлопатать AV. Может, тоже сумбурно объяснил smile

Автор: Tronix 15.10.2009, 17:23
Цитата(kami @ 15.10.2009,  17:12)
\из процедруы кнопки и поставить его в private (или любую другую) секцию формы. Дело в том, что NewThread при первом нажатии на кнопку <> NewThread при последующих, по выходу из процедуры все переменные, обхявленные в этой процедуре "локально" просто забываются и при новом вызове процедуры в них содержится ерунда, никоим боком не относящаяся к тому, что в них было ранее.


Так так так, улавливаю суть. Сейчас попробуем, спасибо за мысль. По результату отпишусь.

UPD: Вроде получилось, когда вывел переменную из функции в глоб преременные. Спасибо за помощь.

Автор: Tronix 15.10.2009, 20:42
А еще такой вопрос - когда вызываем Thread.Suspend - поток сразу останавливается, или как-то надо подождать его остановки? Вот допустим вызвал я Suspend из основной формы, а в процедуре Execute еще какое-то действие происходит. Как поведет себя поток?

PS: Кому интересно, пишу эмулятор приставки chip8 (не совсем прставки, а интерпретируемого ассемблера для нее, но об этом в вики).

Автор: MetalFan 15.10.2009, 22:03
1. не делать ни в коем случае suspend/resume потоку, если не понимать, как это работает.
2. прочитать статью про потоки в делфи в разделе винапи на этом форуме.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)