2008-09-25 6 views
7

Aplikacja ma gwint pomocniczy. Ten wątek nie jest uruchamiany przez cały czas, ale proces główny może go wywoływać bardzo często.Czy optymalne jest umieszczanie nici w zawieszeniu?

Moje pytanie brzmi, co jest bardziej optymalne pod względem wydajności procesora: zawiesić wątek, gdy nie jest używany lub utrzymywać go przy życiu i używać funkcji WaitForSingleObject w celu oczekiwania na sygnał z głównego procesu?

Odpowiedz

14

Jeśli chodzi o zasoby procesora, oba rozwiązania są takie same - wątek zawieszony i wątek oczekujący w obiekcie WaitForSingleObject dla obiektu, który nie jest sygnalizowany, nie otrzymują wcale cykli procesora.

To powiedziawszy, WaitForSingleObject jest prawie zawsze preferowanym rozwiązaniem, ponieważ kod z niego korzystający będzie znacznie bardziej "naturalny" - łatwiejszy do odczytania i łatwiejszy do wykonania. Zawieszanie/Wznawianie wątków może być niebezpieczne, ponieważ musisz zachować ostrożność, aby upewnić się, że wiesz, że zawieszasz wątek w stanie, w którym zawieszenie go nie zaszkodzi (wyobraź sobie zawieszenie wątku, który aktualnie trzyma muteks).

1

Co masz na myśli, mówiąc "zawiesić"? WaitForSingleObject zawiesi wątek, tzn. Nie zużyje żadnego procesora, dopóki nie nadejdzie sygnał.

1

Jeśli jest to wątek roboczy, który ma jednostki pracy nadane mu zewnętrznie, zdecydowanie powinien używać obiektów sygnalizujących, ponieważ to zapewni, że nie będzie on zużywał niepotrzebnie CPU.

Jeśli ma do wykonania jedną ze swoich prac, to już inna sprawa. Nie zawiesiłbym wątku z innego wątku (co się stanie, jeśli działają w nim dwa wątki?) - moją podstawową zasadą jest to, że wątki powinny sterować własnym życiem za pomocą sugestii z innych wątków. To lokalizuje całą kontrolę w samym wątku.

6

Założę się, że Andrei nie używa Delphi do pisania .NET, a zatem Suspend nie tłumaczy się na System.Threading.Thread.Suspend, ale na SuspendThread Win32 API.

Zdecydowanie zasugerowałbym przeciw temu. Jeśli zawiesisz wątek w dowolnym momencie, wtedy nie wiesz, co się stanie (na przykład możesz zawiesić wątek w takim stanie, że niektóre zasoby udostępnione są zablokowane). Jeśli już wiesz, że wątek jest w stanie zawieszenia, po prostu użyj WaitForSingleObject (lub innego wywołania WaitFor) - będzie równie skuteczny jak zawieszenie wątku, tzn. Wątek będzie używał zerowego czasu CPU, dopóki się nie obudzi.

0

Inną opcją byłoby TMonitor wprowadzony w Delphi 2009, który posiada funkcje jak Wait, puls i PulseAll zachować wątki nieaktywne, gdy nie ma nic do zrobić dla nich i powiadomić ich tak szybko, jak powinni kontynuować swoją pracę. Jest luźno zamodelowany po blokadach obiektów w Javie. Tak jak tam, obiekt Delphi ma teraz pole "lock", które może być użyte do synchronizacji wątków.

blog, który daje przykład dla gwintowaną klasy kolejki można znaleźć na http://delphihaven.wordpress.com/2011/05/04/using-tmonitor-1/

Niestety nie był to błąd w realizacji TMonitor, który wydaje się być ustalona w XE2