Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как корректно завершить работу потоков в программе!? [D6, Win95/98]


Zergling ©   (2002-10-30 06:15:00) 

Доброго всем дня! Такой вот вопрпосец мастера. Моя программа воспроизводит звуковые сообщения в потоке.
Создается очередь потоков с помощью CriticalSection. Когда я закрываю программу (а в очереди есть еще потоки), то соответсвенно чаще всего система намертво виснет.
Как избежать такой ситуации или передать сообщение всем созднным потокам в очереди что, они должны немедленно звершить свою работу (уничтожиться)?

Заранее всем спасибо


Nomad.kz   (2002-10-30 15:12:00) [1]

я делал много потоков в одной проге, дык хранил их в TList - очень удобно. Как здесь советуют многие, в Execute надо в цикле смотреть Terminated и если true than Exit. чтобы завершить все потоки, например, можно воспользоваться таким методом:
lst:TList;
th:=TThreadMy.Create(true,...);
th.Resume;
lst.Add(th);
...
while lst.Count>0 do begin
TThread(lst[i]).Terminate;
TThread(lst[i]).WaitFor;
lst.Delete(i);
end;


VaS   (2002-10-30 12:20:00) [2]

Так получше будет :)


procedure TTr.Execute;
begin
while not Terminated do
if Q.AtLeast(1) then
Play(TMusic(Q.Pop))
else
Sleep(10);
end;


Alex4444444444   (2002-10-30 12:03:00) [3]

AFAIK, Free vyzyvaet Terminate. Drugoj vopros, chto esli Execute napisano negramotno (ili esli, ne day Bog, thread suspended), to
ni Terminate, ni Free ne srabotayut: oba budut zhdat", poka Execute zavershitsya, a ona ne smozhet zavershitsya, esli ona suspended... Ya soglasen, chto luchshe imet" odin Thread i v Execute kak mozhno chashe proveryat" na Terminated. V glavnoj programme mozhno budet skazat"

Thread.Terminate;
WaitForSingleObject(Thread.Handle, ...)

Vprochem, WaitForSingleObject vstroeno v TThread.Free.


Zergling   (2002-10-30 11:58:00) [4]

Polevi ©

семафор вроде бы выступает как подобие критической секции. Как они мне могут помочь в уничтожении потоков? Если можно подробней пожалуйста. Где копать то? Может я про семафоры что то не то понимаю.


VaS   (2002-10-30 11:38:00) [5]

> потоки создаются с помощью CriticalSection т.е. вновь
> созданный поток ждет пока не завершится предыдуший поток,
> только после завершения работы предыдущего потока, вновь
> созданный поток начнет свою работу.

В таком случае вопрос - зачем тебе куча потоков? Создай нитивую очередь (сделай из TQueue по аналогии с TList), добавляй туда твои звуки (или что там тебе нужно), а в единственнойнитке, живущей постоянно (и убиваемой при завершении программы), разгребай эту очередь. Что-то типа:

Добавили где-то в другой (главной) нитке:


Q.Push(Music);


Обрабатываем:


procedure TTr.Execute;
begin
while not Terminated do
begin
while Q.AtLeast(1) do
begin
Play(TMusic(Q.Pop));
end;
Sleep(10);
end;
end;


MrAngel   (2002-10-30 11:32:00) [6]

хмм интересный вопрос ты задал...
В моеё проге тоже есть потоки однако преждевременный выход из потока я делаю через переменную обьявленную в нём, т.е. если оно имеет TRUE то надо выходить...

В твоём же случае процедура проигрывания файла (или просто звука) не может делать такие обработки. Я вижу выход только в одном:
1. В самом начале Execute сделай FreeOnTerminate := True;
2. Когда надо сделать досрочный выход в главном модуле своей программы, где обьявлен обьект потока напиши YourThread.Terminate;
А затем YourThread.Free/ -
По идее такая фишка должна сработать...

Удачи...


Polevi   (2002-10-30 11:00:00) [7]

семафор тебе в руки


Zergling   (2002-10-30 10:54:00) [8]

SottNick ©
потоки создаются с помощью CriticalSection т.е. вновь созданный поток ждет пока не завершится предыдуший поток, только после завершения работы предыдущего потока, вновь созданный поток начнет свою работу. Втом то и дело, что у меня нет ни ккого массива потоков, переменная класса TThread у меня всего одна. А раз переменная одна ,наверное они с одинаковым именем. Как же я их все в цикле поубиваю??? Создавать переменные с разным именем безполезно т.к. не известно точно сколько будет воспроизводится звуковых сообщений у меня в программе, следовательно неизветсно сколько нужно для этих целей переменных.


SottNick   (2002-10-30 09:48:00) [9]

2 Zergling
что это за тип такой "пачка потоков"?
или, другими словами, проделай это с каждым в цикле или как ты там их создаешь...


Zergling   (2002-10-30 09:30:00) [10]

SottNick

скорей всего твой метод подходит для уничтожения 1-го потока. Как я писал выше, у меня создаются целая пачка потоков. Вот эту пачку надо уничтожить при закрытии приложения. Такая вот проблема.


Bis   (2002-10-30 08:30:00) [11]

2mmb
оно может подойти, если поток каким-то образом узнает о том, что нужно завершить работу. В принципе в Execute можно вставить проверку какую-нибудь на то, что программе надо срочно завершить работу. С другой стороны программа тогда должна подождать завершения всех потоков.


mmb   (2002-10-30 07:56:00) [12]

А чем Terminate;с FreeOnTerminate := True;не подходит?


SottNick   (2002-10-30 07:18:00) [13]

if MyThrd<>nil
then
begin
MyThrd.Suspend;
MyThrd.Free;
MyThrd:=nil;
end;

должно помочь
при принудительном завершении потока память почему-то не освобождается
ЕСЛИ РЕШИШЬ ПРОБЛЕМУ, НАПИШИ


Наверх

Титульная страница Поиск, карта сайта Написать письмо