Kilka pytań o wielowątkowość

Odpowiedz Nowy wątek
2008-02-12 23:10
kolpo
0

Piszę program w C++, mam parę pytań:

Mam obiekt reprezentujący wątek, czy muszę na końcu metody Execute wywoływać metody Free oraz Terminate jeżeli od razu po zakończeniu Execute obiekt ten będzie usunięty z pamięci operatorem delete?

Za każdym razem gdy chce usunąć obiekt typu TThread, który ma ustawiony FreeOnTerminate na true program się wysypuje, czy wie ktoś dlaczego tak się dzieje?

Mam pewien obiekt typu Tthread, zaplanowałem sobie, że za każdym razem gdy użytkownik naciśnie button`a będzie wykonywana metoda Execute (oczywiście za pomocą Resume), niestety wątek zostaje odpalony tylko za pierwszym razem, potem już metoda Resume nie uruchamia Execute. Da się zrobić taki obiekt-wątek wielokrotnego użytku czy może trzeba za każdym razem tworzyć nowy obiekt??

Pozostało 580 znaków

2008-02-13 00:05
0
kolpo napisał(a)

Mam obiekt reprezentujący wątek, czy muszę na końcu metody Execute wywoływać metody Free oraz Terminate jeżeli od razu po zakończeniu Execute obiekt ten będzie usunięty z pamięci operatorem delete?
po 1 nie da się zrobić free na samym sobie, po 2 Terminate jest zupełnie do czego innego.

Za każdym razem gdy chce usunąć obiekt typu TThread, który ma ustawiony FreeOnTerminate na true program się wysypuje, czy wie ktoś dlaczego tak się dzieje?
i pewnie nie przyszło ci do głowy sprawdzić w helpie|googlach co robi FreeOnTerminate, BTW bardzo ciężko się domyśleć po nazwie...

Mam pewien obiekt typu Tthread, zaplanowałem sobie, że za każdym razem gdy użytkownik naciśnie button`a będzie wykonywana metoda Execute (oczywiście za pomocą Resume), niestety wątek zostaje odpalony tylko za pierwszym razem, potem już metoda Resume nie uruchamia Execute. Da się zrobić taki obiekt-wątek wielokrotnego użytku czy może trzeba za każdym razem tworzyć nowy obiekt??
może poczytaj cokolwiek o wątkach najpierw bo z tego co piszesz to pojęcia nie masz jak one działają.

Podstawowa wiedza ci nie zaszkodzi, a wysiłek włożony w jej zdobycie nie powinien cię zabić ...


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2008-02-13 09:35
0

Miałem ten sam problem, ale okazało się, że uzupełnienie początku destruktora o linijki:

while(suspended) resume();
WaitFor();

rozwiązuje problem (mimo, że to trochę dziwne).
Linijki te są potrzebne tylko wtedy, gdy w destruktorze zwalniasz pewne zasoby.
Innym rozwiązaniem jest rezygnacja z destruktora i zwalnianie zasobów na końcu Execute().


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2008-02-13 11:34
0

Marek... czekaj, jaki ten sam problem? Że niby to niżej?

chce usunąć obiekt typu TThread, który ma ustawiony FreeOnTerminate na true program się wysypuje, czy wie ktoś dlaczego tak się dzieje

no nie róbcie sobie jaj, proszę ja was bardzo. Wątek się zwalnia automatycznie po wykonaniu, wy próbujecie zwolnić zwolniony już obiekt, czyli NIEISTNIEJĄCY, i robicie wielkie oczy, że program się sypie?

a Suspend / Suspended/ Resume służą do wstrzymywania i kontynuowania wątku. Takie Pause/Play. Co to w ogóle robi w destruktorze?

Znaczy ok, rozwiązanie zmyślne, tak na mój gust, po nie pozwala się zniszczyć obiektowi, który został wstrzymany, tylko wymusza pełne wykonanie zawartości Run, zanim wątek wyląduje w krainie wiecznego wywłaszczania. To mogłoby mieć zastosowanie w wątku, który musi po sobie zostawić spójne dane, na których pracuje. Może w VCL/WinAPI można to zrobić inaczej, ale to mi się podoba, nawet mimo tego, że może brzydko zakleszczyć program ;P

No ale nie ma to związku z podwójnym deletem, albo wywoływaniem resume x razy pod rząd na działającym już wątku:

za każdym razem gdy użytkownik naciśnie button`a będzie wykonywana metoda Execute (oczywiście za pomocą Resume),

Bo to są błędy, do jasnej Anielki!

Pozostało 580 znaków

2008-02-13 11:57
0

Da się zrobić taki obiekt-wątek wielokrotnego użytku czy może trzeba za każdym razem tworzyć nowy obiekt??

Da się , przy pomocy tworzenia nowego obiektu "wątku" i zakończeniu poprzedniego .


Pozostało 580 znaków

2008-02-13 14:27
0

@Ranides: założyłem, że niszczy obiekt jedynie przez ustawienie FreeOnTerminate=true; a nie potem jeszcze przez zastosowanie delete.
A ten problem u mnie pojawił się tutaj.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2008-02-13 22:02
0

Aaaa, jak takie założenie zrobiłeś, to zwracam honor. Pętla tak jak mówisz, dziwna. W teorii powinna (IMO), jak pisałem, po prostu podczas destrukcji odpauzowywać wstrzymany wątek i czekać na jego zakończenie.

W teorii na FreeOnTerminate nie powinna wpływać, bo terminate przecież następuje po zakończeniu wątku i jego pauzowanie/odpauzowanie nie ma sensu, bo on już nie działa... W praktyce to jest VCL i WinAPI, Borland+Microsoft naraz mogli niejedno cudo stworzyć, a ponieważ w temacie, który wskazujesz, sami też cuda wianki wydziwiacie ;P (nie używam wątków w VCL w praktyce, więc całość dyskusji sobie darowałem...) to głęboko wierzę, że to "coś" robi więcej, niż mi się wydaje ;)

Pozostało 580 znaków

2008-02-13 23:05
kolpo
0

Nie wiedziałem, że Free() wywołuje jednocześnie destruktor stąd się wzięły moje głupie pytania :-)

Jaka jest różnica (jeżeli jest jakaś) pomiędzy wywoływaniem Free(), a wywoływaniem delete wskaźnik? Czy zawsze powinno się używać Free()?

Czy dobrze rozumiem, że funkcja WaitFor() czeka aż metoda Execute skończy się wykonywać?

Taki problem jeszcze mnie nurtuje:

wywołanie metody Free bądź usunięcie obiektu za pomocą operatora delete zakleszcza program, jeżeli wątek w chwili usuwania jest suspended. Jak w takim razie pozbyć się tego wątku jeżeli nie chcę go uruchamiać?

Pozostało 580 znaków

2008-02-13 23:30
0

Hmmm, po kolei, chociaż nie na wszystko w sposób zadowalający:

  1. już wiesz :)
  2. zasadniczo, to chyba żadna. Free to metoda destrukcji, którą Builder otrzymał w spadku po Delphi. znając życie, to Free używa delete, albo destruktor podczas niszczenia używa Free.
  3. dobrze
  4. naprawdę, zakleszcza? :> nie wiem, ja nigdy nie usuwałem wątków, dopóki same nie ogłosiły wszem i wobec, że skończyły - ogólnie, to strasznie złe rzeczy chodzą ci po głowie ;) Może ubij taki wątek na chama:
    TerminateThread(ObiektThread->Handle);
    to zadziała na 100%, niczego nie zakleszczy, ale poczytaj w dokumentacji, kiedy z tym uważać, bo możesz trochę stabilność systemu popsuć albo śmieci w pamięci zostawić.

Pozostało 580 znaków

2008-02-14 08:46
0

Co do niszczenia niezakończonego wątku (TThread), to helpie można znaleźć wyraźną radę by tego unikać. Zalecają by w metodzie Execute sprawdzać cyklicznie wartość Termineted i na tej podstawie zakańczać wykonywanie metody Execute (wątku). Ta wskazówka jest tak wyraźna, że nie ma jasnej metody jak niszczyć wątek przed zakończeniem (dla klasy TThread bo na siłę można zastosować API).


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2008-02-14 10:37
0
MarekR22 napisał(a)

Ta wskazówka jest tak wyraźna, że nie ma jasnej metody jak niszczyć wątek przed zakończeniem (dla klasy TThread bo na siłę można zastosować API).
jest i to bardzo dokładna - trzeba tak oprogramować metodę execute żeby nie trzeba było go ubijać na chama


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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