WZAJEMNE WYKLUCZANIE Wiele metod. Np. wyłączanie przerwań: funkcja() //... Int blokada = intlock(); // Obszar krytyczny, któremu nie możemy przerwać intunlock(blokada); wyłączanie wywłaszczania: funkcja() tasklock(); // Obszar krytyczny, który nie może być wywłaszczony //... taskunlok(); 1//9
SEMAFORY VxWorks Binarne, wzajemnego wykluczania (mutex), całkowite (counting) Funkcje do ich obsługi: sembcreate() - tworzy i inicjalizuje semafor binarny semmcreate() - tworzy i incjalizuje semafor wzajemnego wykluczania semccreate()` - tworzy i inicjalizuje semafor całkowity semdelete() - usuwa semafor semtake() - pobiera semafor semgive() - oddaje semafor semflush - odblokowuje wszystkie zadania oczekujące na dany semafor #include VxWorks.h #include semlib.h SEM_ID semafor; // Utworzenie semafora zainicjowanie (dostępny), zadania w kolejce wstrzymanych // ustawione wg priorytetów semafor = sembcreate(sem_q_priority, SEM_FULL); 2//9
SEMAFORY VxWorks c.d. Przykład użycia semafora binarnego do wzajemnego wykluczania semtake(semafor, WAIT_FOREVER); // Obszar krytyczny tylko jedno zadanie może być w posiadaniu semafora // Zadanie będzie czekało do skutku na semafor semgive(semafor); Semafory binarne bywają używane do synchronizacji zadań (zdarzeń), W takim przypadku zwykle kreuje się semafor od razu pusty. Zadanie, które chce oczekiwać na zdarzenie jest wstrzymane aż do zwolnienia semafora przez zdarzenie 3//9
SEMAFORY VxWorks c.d. #include VxWorks.h #include semlib.h SEM_ID semafor; // Utworzenie semafora i zainicjowanie (pusty), // zadanie_x będzie czekało na zdarzenie zadanie_x (void) // Wstrzymanie zadania w oczekiwaniu na zdarzenie semtake(semafor, WAIT_FOREVER); ) //Przykładowa procedura obsługi przerwania, reprezentująca zdarzenie procedura_obslugi_przerwania(void) // Oddanie semafora, uwolnienie wstrzymanego zadania semgive(semafor); 4//9
SEMAFORY VxWorks c.d. Semafory VxWorks posiadają opcje (nie ujęte w standardach POSIX), przeterminowania kolejek (FIFO lub priorytetowych) KOLEJKI KOMUNIKATÓW msgqcreate () - utworzenie i zainicjowanie kolejki komunikatów msgqdelete - usunięcie kolejki komunikatów msgqsend () - wysłanie komunikatu do kolejki msgqrceive () - odebranie komunikatu z kolejki komunikatów Kreowanie definiuje liczbę maksymalną komunikatów i maksymalną długość komunikatu Jeśli żadne zadanie nie oczekuje na komunikat, to jest on dodawany do kolejki. Jeśli są zadania oczekujące na komunikat, to jest on dostarczony bezzwłocznie pierwszemu z nich 5//9
KOLEJKI KOMUNIKATÓW c.d.. Jeśli są zadania oczekujące na komunikat, to jest on dostarczony bezzwłocznie pierwszemu z nich. Jeśli komunikaty są w buforze, to pierwszy jest pobierany przez zadanie wywołujące. Jeśli nie ma komunikatu, to zadanie wywołujące jest blokowane i oddawane do kolejki zadań oczekujących na komunikaty. Kolejka zadań oczekujących na komunikaty może mieć kolejność wynikającą z priorytetów lub kolejność FIFO. (To określane jest na etapie tworzenia kolejki). Przeterminowanie Komunikaty pilne 6//9
KOLEJKI KOMUNIKATÓW c.d. Przykład użycia kolejek komunikatów #include VxWorks.h #include msgqlib.h #define MAX_MSGS (10) #define MAX_MSG_LEN (100) MSG_Q_ID kolejka_komunikatow; zadanie_2(void) char bufor_komunikatów[max_msg_len]; //Pobranie komunikatu z kolejki lub oczekiwanie na if(msgqreceive(kolejka_komunikatow, bufor_komunikatow, MAX_MSG_LEN, WAIT_FOREVER) == ERROR) return (ERROR); 7//9
KOLEJKI KOMUNIKATÓW c.d. #define MESSAGE Treść komunikatu zadanie_1(void) //Utworzenie kolejki komunikatów if((kolejka_komunikatow = msgqcreate(max_msgs, MAX_MSG_LEN, MSG_Q_PRIORITY)) == ERROR) return (ERROR); //Wysyłanie komunikatu o zwykłym priorytecie lub czekanie na miejsce w kolejce if(msgqsend (kolejka_komunikatow, MESSAGE, sizeof(message), WAIT_FOREVER, MSG_PRI_NORMAL) ERROR) return(error); //... Realizacja struktury klient serwer POTOKI KOMUNIKACJA SIECIOWA SYGNAŁY... (SZEREGOWANIE KARUZELOWE!!! ) 8//9
9//9