Autor Wątek: Eliminacja z kodu "while(warunek);" (while który tylko czeka...)  (Przeczytany 1910 razy)

Offline Adam B

  • Użytkownik

# Grudzień 01, 2011, 12:49:52
Hej,

W kilku miejscach w programie wielowątkowym mam kod w stylu:

Pseudokod:

Inicjalizacja Akcji..

//Ta akcje wykonuje inny wątek
while(!AkcjaWykonana());

Odpowiedź  na akcję...


Oto przykład prawdziwego kodu:
while (true)
            {
                //Jezeli są jakieś rozkazy do wykonania....
                if (OrderForServer.getSize() > 0)
                {
                    byte[] ActualOrderByte = null;

                    //początek zamknięcia
                    ServerSystem.safeRW.EnterWriteLock();
                    ActualOrderByte = OrderForServer.getFirstUndoneOrder();

                    if (ActualOrderByte != null)
                    {

                        SetTextInTextBox("OrderBuffer: " + OrderForServer.getSize(), textBoxLastOrder);

                        int RqType = RequestCrp.getType(ActualOrderByte);
                        byte[] RqData = RequestCrp.getData(ActualOrderByte);

                        //TUTAJ SĄ AKCJE DLA DANYCH

                        OrderForServer.setFirstOrderResult(AnswerData);
                        OrderForServer.setFirstOrderDone();

                    }
                    //Koniec wykonania
                    ServerSystem.safeRW.ExitWriteLock();
                }
                else
                {
                    SetTextInTextBox("ObrderBuffer: " + OrderForServer.getSize(), textBoxLastOrder);
                }
            }

W tym przykładzie wątek ciągle sprawdza czy są jakieś zadania dla menadżera rozkazów serwera, co w efekcie daje, że rdzeń procesora jest cały czas zajęty na maksa :/

Akcje dla menadżera dodają inne wątki, które odbierają dane wejściowych od klienta.. W efekcie daje to następujący efekt:

Menadżer Rozkazów czeka na nowe zadania w pętli while.
Wątek obsługujący połączenia z klientem po dodaniu akcji do Menadżera Rozkazów też czeka (za pomocą while (!TOrder.isDone()); ) aż wątek zostanie wykonany, a następnie odpowiada klientowi...


Chciałem Wyeliminować z kodu "while(coś)" lub zrobić to tak aby procesor nie był obciążany maksymalnie gdy nie ma nic do roboty...

Pozdrawiam,
Adam

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline pawelek

  • Użytkownik

# Grudzień 01, 2011, 13:07:51
Daj mu czasem trochę wytchnienia robiąc sleep().

Offline .:NOXY:.

  • Użytkownik
    • Profil

# Grudzień 01, 2011, 13:55:47
zrob to w druga strone?

nie jako "while(sadane)" tylko jako interfacesieciowy()->dostaldane()// i tu magia wywoalnie callbacka do twojego kodu.


Offline revo

  • Użytkownik

# Grudzień 01, 2011, 14:18:43
http://en.wikipedia.org/wiki/Sleeping_barber_problem -- chyba mniej więcej o coś takiego chodzi ;)

Offline bies

  • Użytkownik

# Grudzień 01, 2011, 15:25:45
Implementacja na semaforach z Wikipedii jest oczywiście poprawna ale wykorzystywanie semaforów jest kłopotliwe. Łatwiej jest użyć zmiennej warunkowej (klasa Monitor) (producent robi Pulse a konsument Wait na zmiennej).

// edit
Nie zauważyłem, że pytanie jest w dziale C# i dałem kod w C++. W każdym razie owyn podał odpowiednie namiary na rozwiązanie w C#. ;)
« Ostatnia zmiana: Grudzień 01, 2011, 15:37:27 wysłana przez bies »

Offline pawelek

  • Użytkownik

# Grudzień 01, 2011, 15:44:08
O ja też myślałem, że to C++ :)

Offline MrKaktus

  • Użytkownik

# Grudzień 01, 2011, 16:38:19
Wiem że wyskoczę teraz totalnie nie z tematu, ale przyszło mi do głowy że to idealny problem który aż prosi się aby go rozwiązać Task Poolem. W takim przypadku watek spalzowalby po prostu task do momentu zakonczenia zadania na ktore on oczekuje, a w miedzyczasie zaczalby wykonywac kolejne zadanie z kolejki :).

Offline agent_J

  • Użytkownik

# Grudzień 01, 2011, 20:57:31
Poczytaj sobie o wait condition.

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Grudzień 01, 2011, 21:36:13
Do czekania w wątku bez zużywania cykli procesora służą obiekty synchronizujące. Różne biblioteki do wielowątkowości mają je różne. WinAPI ma semafory i eventy (poszukaj np. CreateSemaphore, CreateEvent), pthreads ma semafory i zmienne warunkowe (conditional variables).

Offline .:NOXY:.

  • Użytkownik
    • Profil

# Grudzień 02, 2011, 09:23:29
@MrKaktus Widze ze od WGK to ty tylko o jednym :D