XE2 i wstrzymanie wątku

0

Cześć, wszędzie piszą, żeby nie używać metod Suspend i Resume. Nawet w pomocy Delphi znalazłem, żeby zamiast tego użyć np: suspended:=true. Zagłębiłem się i co znalazłem? Ano suspended wywołuje właśnie te metody. WTF?

To teraz pytanie mam takie. Mam wątek, który ma działać do pewnego momentu, potem przestać. Potem ma znowu zadziałać na żądanie. Coś w sensie (bardziej pseudokod)

procedure TMyThread.Execute;
begin
  while not Terminated do
  begin
    FCounter:=FCounter - 500;
    if FCounter<=0 then zakoncz_prace_watku;

    ProcessMessages;
    sleep(500);
  end;
end;

procedure TMyThread.Proc;
begin
  FCounter:=10000;
  if suspended then Start;
end;

Oczywiście używam tutaj sekcji krytycznych jeśli chodzi o zmienną FCounter.
Teraz pytanie jest takie. Co będzie najlepsze? Dać freeOnTerminate i po prostu przerywać wątek i tworzyć za każdym razem, gdy potrzebuję. Czy na chama zamiast Start, wywoływać Execute? A może są jeszcze jakieś inne metody?

0

Wszystko zależy od tego jak często wątek będzie pracował. Jeżeli rzadko, to za każdym razem możesz tworzyć nowy. Jeżeli wątek wykonuje konkretne zadania, które przychodzą dość często to możesz synchronizować przy użyciu zdarzeń - TEvent.

1

Wygląda mi na to że nie potrzebujesz wątku lecz Timer'a

procedure TForm1.Timer1Timer(Sender:TObject);
var T:Integer;
begin
  ProcessMessages; // cokolwiek to u ciebie znaczy
  T:=Timer1.Tag-500;
  Timer1.Tag:=T;
  if T<=0 then Timer1.Enabled:=false;
end;

//odpalenie:
Timer1.Interval:=500; // to może być raz na zawsze we wlaściwościach
Timer1.Tag:=10000;
Timer1.Enabled:=true;
0

ProcessMessages;
Tak, Procedurka z VCL/LCL w wątku bez syncowania. Bardzo ładna metoda wywracania procesu.

Wszystko zależy od tego jak często wątek będzie pracował. Jeżeli rzadko, to za każdym razem możesz tworzyć nowy. Jeżeli wątek wykonuje konkretne zadania, które przychodzą dość często to możesz synchronizować przy użyciu zdarzeń - TEvent.

Generalnie to niewielkie to ma znaczenie, bo tworzenie nowego wątku jakoś strasznie dużego wpływu na wydajność nie ma, no chyba że jest on zatrzymywany na setne części sekundy, wtedy TEvent to dobre rozwiązanie, bo kernel nie będzie marnować czasu na ten wątek póki event nie odpali.

Wygląda mi na to że nie potrzebujesz wątku lecz Timer'a

Jedynie procedury które są blokujące i nie mamy możliwości przerobienia ich na nieblokujące wymagają wątków. W rzeczywistości takie rzeczy się raczej nie dzieją, gdyż zawsze można przerobić kod na nieblokujący, ale czasami nie warto tracić jego liniowości/robić burdelu z kodu.

Nawet w pomocy Delphi znalazłem, żeby zamiast tego użyć np: suspended:=true. Zagłębiłem się i co znalazłem? Ano suspended wywołuje właśnie te metody. WTF?

(Kod LCL)
procedure TThread.SetSuspended(Value: Boolean);
begin
  if Value <> FSuspended then
    if Value then
      Suspend
    else
      Resume;
end;

Jak widać kod ten zabezpiecza przed wykonaniem dwa razy Suspenda.

To teraz pytanie mam takie. Mam wątek, który ma działać do pewnego momentu, potem przestać. Potem ma znowu zadziałać na żądanie. Coś w sensie (bardziej pseudokod)

Moim zdaniem to ty się najpierw powinieneś nauczyć jak działają inne rzeczy niż wątki, bo ja mimo że mam doświadczenie duże wątki zazwyczaj omijam gdyż powodują one dużo problemów, zazwyczaj nie będąc nawet potrzebnymi.

0
rhred4 napisał(a):

ProcessMessages;
Tak, Procedurka z VCL/LCL w wątku bez syncowania. Bardzo ładna metoda wywracania procesu.

What? PeekMessage, TranslateMessage i DispatchMessage dodatkowo z sekcją krytyczną. O co Ci chodzi?

Wygląda mi na to że nie potrzebujesz wątku lecz Timer'a

Jeszcze to badam

Jedynie procedury które są blokujące i nie mamy możliwości przerobienia ich na nieblokujące wymagają wątków. W rzeczywistości takie rzeczy się raczej nie dzieją, gdyż zawsze można przerobić kod na nieblokujący, ale czasami nie warto tracić jego liniowości/robić burdelu z kodu.

No daj spokój, wg Ciebie w ogóle nie powinniśmy używać wątków, bo wszystko da się zrobić bez nich?

Moim zdaniem to ty się najpierw powinieneś nauczyć jak działają inne rzeczy niż wątki, bo ja mimo że mam doświadczenie duże wątki zazwyczaj omijam gdyż powodują one dużo problemów, zazwyczaj nie będąc nawet potrzebnymi.

To powiedz mi o tych "innych rzeczach niż wątki"

0

What? PeekMessage, TranslateMessage i DispatchMessage dodatkowo z sekcją krytyczną. O co Ci chodzi?

Przysłaniasz LCLowe ProcessMessages?
Application.ProcessMessages ma nawet zabezpieczenie przed wykonaniem z niegłównego wątku - exception.
Nie mam pojęcia czy to przysłaniasz, czy uważasz że to będzie działać, ale tak czy siak coś robisz nie tak.

No daj spokój, wg Ciebie w ogóle nie powinniśmy używać wątków, bo wszystko da się zrobić bez nich?

Chyba masz problem z przeczytaniem mojego posta do końca. Dokładnie już się wypowiedziałem. Nawet cytujesz to.

To powiedz mi o tych "innych rzeczach niż wątki"

A czemu ja mam ci cokolwiek mówić? Inni już powiedzieli: timery. Skoro nie jesteś w stanie zrozumieć zalet i wad wątków oraz sposób na ich uniknięcie to widać że nie są one dla ciebie.

0
rhrdru napisał(a):

What? PeekMessage, TranslateMessage i DispatchMessage dodatkowo z sekcją krytyczną. O co Ci chodzi?

Przysłaniasz LCLowe ProcessMessages?
Application.ProcessMessages ma nawet zabezpieczenie przed wykonaniem z niegłównego wątku - exception.
Nie mam pojęcia czy to przysłaniasz, czy uważasz że to będzie działać, ale tak czy siak coś robisz nie tak.

A gdzie ja napisałem: "Application.ProcessMessages" ? To usługa, a więc nie może tego być. I dlatego nie napisałem Application.ProcessMessages, tylko samo ProcessMessages. Wystarczy wygooglać: "service processMessages" i dostaniemy coś takiego:

if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;

To powiedz mi o tych "innych rzeczach niż wątki"

A czemu ja mam ci cokolwiek mówić? Inni już powiedzieli: timery. Skoro nie jesteś w stanie zrozumieć zalet i wad wątków oraz sposób na ich uniknięcie to widać że nie są one dla ciebie.
</quote>
Jakoś znam zalety i wady wątków. Ale zdaje się, że Ty próbujesz ich unikać jak ognia zawsze i wszędzie. To pokazuje, że jednak chyba Ty do końca nie wiesz, po co są wątki. Albo nie spotkałeś się z problemem, w którym musiałbyś ich użyć.

0

A gdzie ja napisałem: "Application.ProcessMessages" ?

Nigdzie tego nie napisałeś, natomiast widoczność nie wskazuje jednoznacznie o co chodzi.

To usługa, a więc nie może tego być.

No i ja powinienem był to przeczytać na mojej magicznej kryształowej kuli. Przecież 99% programów to usługi, prawda?

I dlatego nie napisałem Application.ProcessMessages, tylko samo ProcessMessages.

Wiesz co to zakres widoczności? No to teraz domyśl się dlaczego założyłem zdrowo że chodzi o Application.

Wystarczy wygooglać: "service processMessages"

I znów, szkoda że nie mam magicznej kuli. Będę musiał od monka pożyczyć ekspres do kawy żeby wróżyć z fusów.

Ale zdaje się, że Ty próbujesz ich [wątków] unikać jak ognia zawsze i wszędzie.

Ależ oczywiście, teraz będziesz uczyć ojca dzieci robić.

To pokazuje, że jednak chyba Ty do końca nie wiesz, po co są wątki.

Z całym szacunkiem do ciebie, bo nie uważam że wiedza to wszystko, ale to ty jesteś pytaczem, a ja odpowiadaczem i mogę śmiało założyć że o programowaniu to ja wiem dużo więcej niż ty. Więc wyjdź z takimi śmiesznymi osądami.

Albo nie spotkałeś się z problemem, w którym musiałbyś ich użyć.

Na logikę: Skoro ja jestem odpowiadaczem, to zapewne znaczy że mam wiedzę większą niż większość pytaczy. I doskonale wiem, że wiele problemów gdzie zastosowałem wątki okazywało się problematycznymi właśnie przez nie. Dlatego jestem przeciwnikiem wątków, bo mimo że je stosuję to robię to rozsądnie.
Natomiast w kontraście jesteś ty: Osoba która o timerach nie słyszała, która jest święcie przekonana o magii wątków, która zarzuca bądź co bądź bardziej doświadczonym programistom brak wiedzy. Twoje zarzuty są bezsensowne i raczej nie mają na celu rozmowy czysto technicznej. Zakończ swoje osądy, gdyż to ja jestem tutaj osobą która wie więcej (oceniam to na podstawie twoich wypowiedzi na tym forum). Ja już doskonale przedstawiłem dlaczego wątki są niepotrzebne w 90% sytuacji gdzie jakaś osoba lubiąca gorszy kod może je zastosować. Jeżeli chcesz ze mną polemizować to pokaż że twoja wiedza może równać się z moją. Bo póki co jesteś śmieszny nawet nie znając timerów, a twierdząc że znasz zalety i wady wątków.

Raz jeszcze powtórzę, moje stanowisko wobec wątków jest klarowne, więc nie rozumiem dlaczego ktoś taki jak Ty porywa się na walkę z moimi poglądami, które powstały na podstawie dużej ilości programów oraz kodu. Nie zmuszę ciebie do przepisania kodu na bezwątkowy, mimo że zapewne ułatwiło by to jego design. Natomiast ty nie usiłuj mnie, programisty doświadczonego, kompromitować. To Ty tutaj jesteś osobą która wie mniej, nie ja. Ja prezentuję rozwiązania które stosuję, ty nie musisz ich stosować, natomiast zapewne nie jesteś osobą która może udowadniać ich błędność.

0
dhrh napisał(a):

A gdzie ja napisałem: "Application.ProcessMessages" ?

Nigdzie tego nie napisałeś, natomiast widoczność nie wskazuje jednoznacznie o co chodzi.

OK, tutaj faktycznie moja wina. Myślałem, że jeśli napiszę samo ProcessMessages, to będzie to jednoznaczne, jednak nie do końca jest. Moja wina.

To pokazuje, że jednak chyba Ty do końca nie wiesz, po co są wątki.

Z całym szacunkiem do ciebie, bo nie uważam że wiedza to wszystko, ale to ty jesteś pytaczem, a ja odpowiadaczem i mogę śmiało założyć że o programowaniu to ja wiem dużo więcej niż ty. Więc wyjdź z takimi śmiesznymi osądami.

Jednak tutaj to Ty posługujesz się dziwnymi metodami wnioskowania, sugerując, że skoro pytam ogół społeczności, to mam mniejszą wiedzę i doświadczenie od Ciebie. Ale to już nie temat na tą dyskusję.

Co do tematu - moje pytanie nadal nie zostało rozwiązane(jak poprawnie wstrzymać i wznowić wątek, gdy użycie TEvent nie ma sensu). Natomiast _13th_Dragon miał rację. W tym wypadku wygląda na to, że wystarcza zwykły timer w takiej konstrukcji, jak podał. Testy wprawdzie jeszcze trwają, ale wstępnie wygląda to ok.

0

Twoje pytanie wygląda na coś w rodzaju: - "Wszędzie piszą aby nie dzielić przez zero, więc jak poprawnie używać dzielenia?"
Dla kontekstu który podałeś, dostałeś najlepsze możliwe rozwiązanie. Innego kontekstu nie podałeś.
Twoje pytanie: - "... jak poprawnie wstrzymać i wznowić wątek ..." bez konkretnego kontekstu nie ma sensu.
Bo wstrzymuje się przez Suspend; a wznawia się przez Resume; nawet konstruktor ma parametr czy stworzyć wątek uśpiony, czy nie wydaje ci się że skoro ktoś tak zaprojektował wątki to ich wstrzymanie i wznawianie jest naturalną koleją rzeczy?

0
_13th_Dragon napisał(a):

Twoje pytanie: - "... jak poprawnie wstrzymać i wznowić wątek ..." bez konkretnego kontekstu nie ma sensu.
Rozumiem.

czy nie wydaje ci się że skoro ktoś tak zaprojektował wątki to ich wstrzymanie i wznawianie jest naturalną koleją rzeczy?
Oczywiście tak mi się wydaje. Ale po przejściu na XE2 nagle widzę wszędzie, żeby nie używać ani Suspend, ani Resume. I o to się wszystko rozbija.

0

Skąd wniosek(bardzo dziwny zresztą), że nie słyszałem o timerach?

Byłem przekonany że coś takiego powiedziałeś wcześniej o tym, ale nic teraz nie widzę, więc wynika jedynie to że nie potrafisz ich zastosować zamiast wątków.

sugerując, że skoro pytam ogół społeczności, to mam mniejszą wiedzę i doświadczenie od Ciebie.

To jest założenie statystycznie, nie pewnik. Jeżeli chcesz podyskutować o Delphi to proszę ciebie bardzo, jestem jedną z niewielu osób na tym forum które rozumieją np. jak działają ansistringi...

Co do tematu - moje pytanie nadal nie zostało rozwiązane

Zostało.

Co będzie najlepsze? Dać freeOnTerminate i po prostu przerywać wątek i tworzyć za każdym razem, gdy potrzebuję. Czy na chama zamiast Start, wywoływać Execute? A może są jeszcze jakieś inne metody?

Można się zastanawiać o jakie 'co będzie najlepsze' ci chodzi. Generalnie wątków nie powinno się zawieszać, gdyż nie ma to uzasadnienia logicznego, skoro możemy synchronizować z obiektem etc. . A o tym że bez wątków też się da to inna sprawa.

Faktem jest, że nie wiem wszystkiego i czasem mam wątpliwości. Jeśli Ty ich nie masz i wiesz już wszystko, to gratuluję.

Nie wiem wszystkiego, natomiast zauważyłem że moje pytania tutaj nie mają żadnego sensu gdyż są zbyt zaawansowane dla większości użytkowników (nawet tych brylujących tutaj) i darowałem sobie gdy moje pytanie zostało nazwane 'bez sensu' bo... oni nie rozumieją problemu... Więc bez obaw, również zadaję pytania, ale raczej nie na forum ale do osób prywatnych rozwijających projekty które mnie interesują oraz twórców FPC.

Natomiast nie jestem programistą amatorem i nie programuję od wczoraj.

No zobacz, to tak jak ja. Tylko że jak patrzyłem na twoje pytania to dotyczyły one dosyć oczywistych spraw w sporej części (włączając to). To że programujesz dużo, nie znaczy że programujesz programy zaawansowane i nowatorskie.

jak poprawnie wstrzymać i wznowić wątek, gdy użycie TEvent nie ma sensu

Zatrzymywanie wątku bez TEvent nie ma sensu. Usiłowanie zawieszania wątku świadczy o tym że coś z kodem jest nie tak.

W tym wypadku wygląda na to, że wystarcza zwykły timer w takiej konstrukcji, jak podał

No i kłóciłeś się z moim stwierdzeniem że wątków tutaj nie ma sensu stosować i sam z niego zrezygnowałeś.

1
4y4s napisał(a):

Skąd wniosek(bardzo dziwny zresztą), że nie słyszałem o timerach?

Byłem przekonany że coś takiego powiedziałeś wcześniej o tym, ale nic teraz nie widzę, więc wynika jedynie to że nie potrafisz ich zastosować zamiast wątków.

Po prostu wątków używa się w innych sytuacjach niż timery.

sugerując, że skoro pytam ogół społeczności, to mam mniejszą wiedzę i doświadczenie od Ciebie.

To jest założenie statystycznie, nie pewnik. Jeżeli chcesz podyskutować o Delphi to proszę ciebie bardzo, jestem jedną z niewielu osób na tym forum które rozumieją np. jak działają ansistringi...
</quote>Wszystko jest ładnie opisane w dokumentach, które opisują migracje z np. Delphi 2005 do XE2 ;)

jak poprawnie wstrzymać i wznowić wątek, gdy użycie TEvent nie ma sensu

Zatrzymywanie wątku bez TEvent nie ma sensu. Usiłowanie zawieszania wątku świadczy o tym że coś z kodem jest nie tak.
</quote> I taka odpowiedź mi w zupełności wystarczy.

W tym wypadku wygląda na to, że wystarcza zwykły timer w takiej konstrukcji, jak podał

No i kłóciłeś się z moim stwierdzeniem że wątków tutaj nie ma sensu stosować i sam z niego zrezygnowałeś.
</quote>
Przyznałem, że tu akurat timer wystarczył. Ale mam jeszcze kilka zupełnie innych wątków w swoim systemie i chciałem wiedzieć ogólnie. Dowiedziałem się, że to zależy od konstrukcji i, że nie powinno się ich wstrzymywać. I to mi wystarczy.

0

daruj sobie mastach te wspaniałe wywody o swojej nieomylności...

Ja nie mówię o swojej nieomylności, ja staram się mówić o faktach, ale lubię przedstawiać sprawy w ładniejszym świetle (jeśli jeszcze tego nie zauważyłeś), co jeszcze nie znaczy że kłamię. Jeżeli dla ciebie umiejętność chwalenia się jest negatywna, to widać sam nie masz się czym chwalić i stąd jesteś skromny.
Proponuję tobie rozmową bardziej techniczną, bo póki co mówisz tylko u pierdołach, które mają na celu podkopanie mnie. Skoro uważasz że się mylę, to mi to pokaż. Chętnie dowiem się czegoś nowego, ale twoje komentarze póki co nic nie wnoszą poza flejmem w którym jak obaj wiemy jestem lepszy. Więc tak czy siak grasz w moją grę.

Po prostu wątków używa się w innych sytuacjach niż timery.

Zazwyczaj można użyć jednego i drugiego. Często timery opłacają się bardziej, w niewielu sytuacjach wątki (ale praktycznie zawsze da się ich uniknąć - czasami sporym kosztem).

Wszystko jest ładnie opisane w dokumentach, które opisują migracje z np. Delphi 2005 do XE2

Facepalm... Wiesz, w dokumentacji jest wszystko, tylko np. taki Ty nie umiesz poczytać dlaczego się wątków nie powinno zawieszać, prawda? Ja sam wiele rzeczy często sprawdzam w dokumentacji, tylko że ja nie zaliczam WTFa gdy się okazuje że metoda TThread.Suspend jest deprecated. Dokumentację ma każdy, nie każdy umie z niej skorzystać.
Jako kontrast do tego, przypomniał mi się cytat furiousa, coś w stylu 'najprzydatniejsza w znalezieniu rozwiązania jest znajomość odpowiedzi'. I stąd właśnie fora (to tak dla tych którzy twierdzą że jestem przeciwnikiem for).

Ale mam jeszcze kilka zupełnie innych wątków w swoim systemie i chciałem wiedzieć ogólnie.

Zapewne cały ten kod można napisać bez wątków. Ew. z maksymalnie 1 dodatkowym wątkiem tak żeby to się trzymało kupy w miarę.

Dowiedziałem się, że to zależy od konstrukcji i, że nie powinno się ich wstrzymywać. I to mi wystarczy.

Jak dobrze, że zrozumiałeś. Teraz możesz ten kod przepisać na timery... Ale to twój kod, możesz nawet zawieszać wątki, tylko to świadczy o tym co się w tym kodzie dzieje...

I jako sidenote, zapewne TThread.Suspend nie zostanie usunięte zbyt szybko bo mimo że dla twórcy aplikacji powinien być ostatnią deską ratunku, to jednak byłoby to tworzenie ograniczenia na siłę (i zawsze można samemu to zaimplementować - WinApi [ale sam M$ to odradza ;) ]).

Może podsumuję moje posty dla potomnych:
Zawieszanie wątków jest odradzane gdyż jedyną prawdziwą sytuacją gdy wątek może być 'zawieszony' jest oczekiwanie na coś co można zrobić poprzez TEvent oraz WaitFor*.
Często zamiast wątków opłaca się stosowanie innych sposobów na podzielenie wykonywania kodu. Jedyną sytuacją gdy jest wymagany wątek jest funkcja która nie wraca przez spory okres czasu (co jednak rzadko jest bez odpowiednika z natychmiastowym powrotem). Nawet jeżeli nie jest on wymagany to warto pomyśleć nad wątkiem gdy nasz kod jest długi i liniowy (chociaż to zapewne oznacza słabo napisany kod).

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