[BCB TThread] Usuwanie działającego wątku.

0

No i wszystko jest pięknie , ale oczywiście do czasu .
Dlatego postanowiłem odświeżyć temat.
//Edit , w nowym wątku
aby przyciąć tasiemca , temat w nawiązaniu do :
http://4programmers.net/Forum/viewtopic.php?id=121815&start=10

Miałem zamiar wbudować w komponent funkcję zabijającą
wątek (TThread) który jest w trakcie wykonywania się.
W skrócie wykonać delete na TThread w trakcie wykonywania wątku.

W celach awaryjnych , przy konieczności usunięcia działającego wątku.

Problem w tym że zabicie wątku opartego na TThread działa ładnie na BCB3,BCB4,
BCB5 nie posiadam ,
ale BCB6 tworzy program na podstawie kodu (który działa w wersjach
wcześniejszych) powodujący całkowitą zwiechę utworzonej aplikacji .

   //  Wersja Borlanda (__TURBOC__ == 0x560)
   //  zawiesza program
     pMyThread ->Suspend();
     pMyThread ->FreeOnTerminate = false;
     delete pMyThread ;       // wykończ wątek //<====TU
     pMyThread = NULL ;
   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 

Nie wiem co zrobić , czy zrezygnować całkowicie z funkcji zabijającej
wątek , czy zastosować np. kompilację warunkową zależną od wersji
TURBOC ??
czy jeszcze inaczej ?

Byłbym wdzięczny ,jeśli ktoś mógł by sprawdzić to dla BCB5 lub innych wersjach BCB.
Przesiedziałem trochę czasu pisząc kod pod BCB3, przeniosłem go na BCB6 a tu kicha..

Niżej linki do prostych aplikacji z kodem obrazującym problem [projekt+source]
tak że sprawdzenie nie zajmie dużo czasu.[działa/nie działa,tyle informacji mi wystarczy]
Aplikacja -> dwa guziki + licznik

To działa:
www.win32prog.republika.pl/delthread/delthreadbcb3.rar
www.win32prog.republika.pl/delthread/delthreadbcb4.rar
To nie działa, następuje zawieszenie programu.
www.win32prog.republika.pl/delthread/delthreadbcb6.rar
ps.zamieszczone wersje projektów mogą zawierać odniesienia do pakietów zależnych od wersji bcb , można je usunąć
ręcznie przez edycję pliku .bpr lub zbudowanie projektu od podstaw .

0

Zjażałem do tego projektu który nie działa. Popraw następująco:

void __fastcall MyThread::Execute(void)
{
      int a = 0 ;
      while(!Terminated) // tu jest istotna poprawka
      {
           Form1->Label1->Caption = a++;
           Sleep(300);
      }
}

__fastcall MyThread::~MyThread() //trzeba dopisać destruktor
{
     Terminate(); // ustawia Terminated na true
     while(Suspended) 
          Resume(); // wątek musi wznowić działanie by prawidłowo
                          // się zakończć
      WaitFor();     // poczekaj aż Execute się zakończy
}
0

Dzięki za spojrzenie ale nie w tym rzecz . ;-)
Więc jeszcze raz sprecyzuję :
Chodzi mi o usunięcie obiektu w czasie gdy wątek działa, fun Execute nie jest zakończona .
Nie chcę go kończyć normalnie tylko zamordować , żadnych WaitFor i Terminate.

W celach awaryjnych

Np. przy zamykaniu aplikacji gdy wątek jest niepotrzebny i zbyt dużo czasu zajmuje jego zakończenie , lub
przestał mi się podobać .

W BCB 3 i 4 usunięcie obiektu z działającym wątkiem nie sprawia problemów destruktor
wykonuje się i program leci dalej .(w podanych przykładach nie ma jawniego destruktora , ale to nie zmienia
istoty problemu , we właściwym kodzie jest )
[ pomijam dyskusje czy jest to dopuszczalne czy nie i powstający wyciek pamięci ].

Ten sam kod kompilowany pod BCB wer. 6 daje aplikację która się zawiesza po ->delete Thread .
No i nie wiem dlaczego ...

0

Problem w tym, że w helpie wyraźnie zalecane jest usuwanie wątku w sposób podany przez mnie. Chodzi tu głównie o to by stos wątku został prawidłowo zwinięty i wszystkie zasoby zostały prawidłowo zwolnione.
Jeśli chcesz koniecznie zniszczyć wątek bez zwijania stosu to musisz posłużyć się API:

TerminateThread(WskaznikTThread->Handle,0);
0

I tak chyba zrobię , zobaczę jak to będzie funkcjonować z resztą kodu ,
przerobione poprzednie proste example działają dobrze z TerminateThread na wszystkich wer BCB .
Myślałem że jak poszło na BCB3 bez API to będzie ok. trudno ...
na razie Dzieki ...
Jakoś mi ten Borland zawodzi jeśli chodzi o ekstremalne rozwiązania i to nie pierwszy raz ..hym..

Ps.Pytanie czysto teoretyczne jak API to może po całości trzeba pojechać: [green] .
Nie śledziłem dokładnie działania aplikacji pod debug CPU , ale :
gwałtowne przerwanie wątku prowadzi do pozostawienia pamięci przeznaczonej
dla wątku w danym procesie .[Memory Leak ].
Czy można spróbować pobrać informacje o wątku przed jego śmiercią i na tej
podstawie zredukować ubytek traconej pamięci po zniszczeniu wątku ?
[ np. zmieniając zawartość rejestru stosu ]
Tak mi przyszło na myśl ale nie chcę wyważać otwartych drzwi lub szukać
czegoś co nie jest możliwe do realizacji .
Czy ma to szansę powodzenia, coś w rodzaju funkcji TerminateThread ale nie powodującej
wycieku pamięci ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1