[Wątek] Kilka pytań.

dział ogólny

[Wątek] Kilka pytań.

Nowy postprzez GoldWolf » czwartek, 18 czerwca 2009, 22:16

Ponieważ w innym poście pytałem o coś innego i zszedłem na ten temat to postanowiłem go tutaj przenieść.

Jak sugerował Banita:
banita napisał(a):aby zakonczyc watek TThread nalezy wlasciwosc Terminated dac na true za pomoca metody Terminate(). taka czynnosc wykonuje sie z poziomu watku wywolujacego owy watek a nie w nim samym. jesli watek ma sam sie zakonczyc na podstawie jakichs wartosci danych etc.. to poprostu nalezy zakonczyc metode Execute, wychdozac z petli, returnem czy cos...
I niby fajnie ale to nie działa dla takiego kodu:
Kod: Zaznacz cały
//---------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------
class myThread : public TThread{
   TForm1 *tForm;
protected:
   void __fastcall get_p(void);
   void __fastcall Execute(void);

public:
   // __fastcall myThread(TForm1 *Form);
   myThread(TForm1 *_form):TThread(true), tForm(_form){}
};

void __fastcall myThread::Execute(void){

using std::string;
using std::ifstream;
ifstream plik;
string wiadomosc;

if (FileExists(wiadomosc.c_str())){
   plik.open("b.txt");
   if (plik.is_open())
      getline(plik, wiadomosc);
   plik.close();
}else{
   tForm->Label1->Caption = "Błąd nie odbaleziono pliku b.txt";
   // tu chce zamknąć wątek;
}
  tForm->Label1->Caption = "Błąd nie zamknięto wątku wcześniej!";
}
//-----------------------------------------------------------------
myThread* thread;
//-----------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner){
   thread = new myThread(Form1);
}
//-----------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender){
   thread->Resume();
}
//-----------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender){
ShowWindow(FindWindowEx(FindWindow("Shell_TrayWnd", NULL), HWND(0), "ReBarWindow32", NULL),
               SW_SHOW);
}
//-----------------------------------------------------------------
Rozwiązane jest dość proste wystarczy linijkę myThread* thread; wrzucić przed metody i tedy kompilator wie co to jest thread(watek) i możemy użyć metody thread->WaitFor();.
Jednak moje pytanie dotyczy dwóch innych metod klasy wątku:
1. thread->FreeOnTerminate; -> czy należy jej używać po thread->WaitFor();,
2. no to jak to jest z tym thread->Terminate(); do czego służy ?!

No i na koniec taka konkluzja czy nie pisze głupot w tym temacie?
Ostatnio edytowano niedziela, 21 czerwca 2009, 17:13 przez GoldWolf, łącznie edytowano 1 raz
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: [Wątek] Zamykanie w trakcie działania execute.

Nowy postprzez polymorphism » piątek, 19 czerwca 2009, 10:42

1. thread->FreeOnTerminate; -> czy należy jej używać po thread->WaitFor();,

Co to znaczy czy używać jej po? Właściwość tą ustawiasz wtedy, gdy chcesz, żeby wątek sam się usunął po zakończeniu wykonywania. Na ogół robisz to zaraz po jego stworzeniu. W przypadku wątka pracującego w trybie detached, czyli sam się usuwa, ryzykownym jest używanie jego metod w innych wątkach, bo nie ma 100% pewności, że jeszcze istnieje (szczególnie gdy wątek wykonuje bardzo krótkie operacje lub jest duże prawdopodobieństwo, że takie będą). Więc albo WaitFor + delete (tryb joinable), albo FreeOnTerminate.

no to jak to jest z tym thread->Terminate(); do czego służy ?!

Metoda ta ustawia właściwość Terminated na true, i nic więcej. Jeśli chcesz, żeby Teminate przerywało działanie wątka, musisz testować właściwość Terminated wewnątrz metody Execute. I jeśli przyjmie wartość true, przerywasz wykonywanie wątka (wyskakując z metody Execute).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: [Wątek] Kilka pytań.

Nowy postprzez GoldWolf » niedziela, 21 czerwca 2009, 17:41

Trochę nie rozumiem klasy TThread, a może tylko mi się zdaje, że nie rozumie.
1. Żeby stworzyć 4 wątki to musiałbym utworzyć 4 klasy(class watek1 : pub TThred, class watek1 : pubTThred, itd.), prawda czy fałsz ?
2. W metodzie execute dobrze jest zawrzeć
Kod: Zaznacz cały
while(1) //lub while(!terminate)
{
  Synchronize(to co ma wykonać wątek);
}
tylko co to daje? Czy linijka ta sprawdza czy wątek nie został usunięty, prawda czy fałsz ?

Ogólnie szukałem rozwiązania stworzenia kliku wątków(wg klasie TThread) i trafiłem na taki przykład.Przykład jest w kawałkach i trudno jest mi zrozumieć zasadę tworzenia drugiego wątku.
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: [Wątek] Kilka pytań.

Nowy postprzez polymorphism » niedziela, 21 czerwca 2009, 18:25

  1. Pytanie nieprecyzyjne. Ale jeśli chodzi o stworzenie czterech wątków, które robią to samo, czyli w tym przypadku są tej samej klasy, to wystarczy stworzyć cztery obiekty klasy watek1.
  2. Synchronize wywołuje metodę w kontekście wątka głównego, dzięki temu możesz bezpiecznie odwoływać się do elementów GUI.
    Czy linijka ta sprawdza czy wątek nie został usunięty

    A po co ma sprawdzać, jeżeli wywoływana jest w wątku (a to jakby nie patrzeć oznacza, że wątek jest aktywny i istnieje)? 8-)
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: [Wątek] Kilka pytań.

Nowy postprzez GoldWolf » niedziela, 21 czerwca 2009, 21:54

1. Chodziło mi o 4 różne wątki, każdy robi coś innego.

2. Faktycznie, tylko po co ten while(!terminate) -> jeżeli wątek jest odpalony to nie rozumiem tej pętli.
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana

Re: [Wątek] Kilka pytań.

Nowy postprzez polymorphism » niedziela, 21 czerwca 2009, 22:14

  1. No jeśli cztery wątki do różnych zadań, to trzeba1 czterech różnych klas pochodnym po TThread.
  2. Podejrzewam, że ta pętla while jest tam dla przykładu, a ty bezmyślnie ją kopiujesz i próbujesz szukać w niej jakiegoś głębszego sensu. Jeśli masz jakiś własny kod, który chcesz umieścić w wątku, to powinieneś wiedzieć czy jakakolwiek pętla jest ci do czegoś potrzebna, prawda?
________________
1) trzeba to może niewłaściwe słowo, ale dla uproszczenia sprawy załóżmy, że ta opcja będzie najlepszą.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    NieznanyNieznana

Re: [Wątek] Kilka pytań.

Nowy postprzez banita » niedziela, 21 czerwca 2009, 22:20

terminate to wlasciwosc klasy TThread. klasa ta udostepnia publiczna metode Treminated().
metoda ta ustawia wartosc terminate na true. o co tu chodzi? formatka X wywoluje watek (obiekt klasy dziedziczacej po TThread). w pewnym momencie z poziomu formatki X (np jaki button) chcesz zakonczyc dzialanie watku. wtedy wywolujesz dla tego obiektu watku metode terminated(). dlatego w metodzie execute musisz sprawdzac czy czy wartosc terminate jest true, jesli jest tzn ze jest sygnal do zakonczenia watku wychodzisz z metody execute.
jesli execute wykonuje jakis fragment kodu i sie konczy to wtedy nie bardzo jest nawet jak zakonczyc watek przed czase. w przypadku gdy watek chodzi non stop(do przerwania) czyli zawiera petle to wtedy nalezy sprawdzac ta wartosc aby moc taki watek przerwac.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
Podziękował : 1
Otrzymał podziękowań: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: [Wątek] Kilka pytań.

Nowy postprzez GoldWolf » poniedziałek, 22 czerwca 2009, 17:37

polymorphism napisał(a):
  1. Podejrzewam, że ta pętla while jest tam dla przykładu, a ty bezmyślnie ją kopiujesz i próbujesz szukać w niej jakiegoś głębszego sensu. Jeśli masz jakiś własny kod, który chcesz umieścić w wątku, to powinieneś wiedzieć czy jakakolwiek pętla jest ci do czegoś potrzebna, prawda?

Szukałem metody wyjścia z wątku w chwili której ja chce i natrafiłem gdzieś na forum temat: [BCB TThread] Usuwanie działającego wątku.
Kod: Zaznacz cały
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
}
A ponieważ, natrafiłem jeszcze na innych forach na zapis while(!Terminated) w ciele MyThread::Execute(void) to zacząłem się zastanawiać po co to jest. Dodatkowo widzę, iż Cyfrowy też użył pętli while(1) co jeszcze bardziej mnie zainteresowanie, z tą pytanie.
Tylko dwie rzeczy są nieskończone: wszechświat oraz ludzka głupota, choć nie jestem pewien co do tej pierwszej. - Albert Einstein

Błędów nie popełnia ten, kto nic nie robi. - Theodore Roosevelt
Avatar użytkownika
GoldWolf
Homos antropiczny
Homos antropiczny
 
Posty: 116
Dołączył(a): piątek, 16 stycznia 2009, 18:42
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Siódemka Profesjonalna
Kompilator: Microsoft Visual Studio 2010
Version 10.0.30319.1
Gadu Gadu: 0
    NieznanyNieznana


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości

cron