Dlaczego używane są semafory?
Korzystając z wątków, napotykamy kilka problemów warunkowych obejmujących warunki wyścigu. Dzieje się tak, gdy dwa lub więcej wątków potrzebuje tych samych danych lub informacji w tym samym czasie, w którym powoduje konflikt. Aby uniknąć tego rodzaju sprzecznej sytuacji, używamy semaforów. Istnieją trzy główne rodzaje semaforów. Jeden to binarna semafor, a drugi to liczenie semafora.
Używamy różnych funkcji w zakresie semaforu, takich jak sem_wait, sem_post i sem_init. SEM_INIT jest przedmiotem rozważanym dalej w tym artykule.
Sem_init
Jak omówiliśmy powyżej, aby zainicjować semafor w wątkach, używamy funkcji SEM_INIT. Tutaj używamy flagi lub banera, który identyfikuje dzielenie się procedurą semaforów z Fork ().
Składnia
# sem_init (sem *sem, int pshared, int value (unsigned));
Sem: Ta funkcja pomaga semaforowi być w stanie gotowym.
Pshared: Ten argument parametrów ma fundamentalne znaczenie w deklaracji semafora. Jak określa status nowo zainicjowanego semaforu. Czy powinno być udostępnione między procesami lub wątkami. Jeśli wartość jest niezerowa, oznacza to, że semafor jest udostępniany między dwoma lub więcej procesami, a jeśli wartość wynosi zero, oznacza to, że semafor jest udostępniany między wątkami.
Wartość: Określa wartość, która ma być przypisana do nowo utworzonego semaforu, który jest początkowo przypisany.
Implementacja SEM_INIT
Aby wykonać semafory w programie C, potrzebujemy kompilatora GCC. Ale to nie wystarczy. „-Lpthread” służy do wykonywania kodu. 'A.C 'to nazwa pliku. Inną rzeczą jest to, że tutaj używamy '.OUT „Z nazwą pliku zamiast korzystania z pliku niezależnie.
Przykład 1
Najpierw dodajemy dwie biblioteki o semaforach i pthread, aby oddać użycie pakietów C. Podobnie jak sem_init inne semafory są używane w tym programie; Tutaj omówimy je.
Sem_wait ()
Ta funkcja służy do przechowywania semafor. Jeśli wartość podana do semaforu jest ujemna, wywołanie jest zablokowane, a cykl jest zamknięty. Podczas gdy każdy inny wątek, po wywołaniu, zablokowane semafory są obudzone.
Sem_post ()
Metoda SEM_POST służy do zwiększenia wartości semafora. Wartość jest zwiększana o sem_post, gdy jest wywoływana.
Sem_destroy ()
Jeśli chcemy zniszczyć semafor, używamy metody sem_destroy. Teraz skoncentruj się na dostarczonym tutaj kodzie źródłowym. Po pierwsze, używana jest tutaj funkcja „oczekiwanie”. Spowoduje, że wątek czeka najpierw, aby inni mogli wykonać zadanie. Wyświetlany jest komunikat, że wątek jest wprowadzany podczas wywoływania funkcji. Następnie wymagana jest funkcja „snu” przez 5 sekund.
Dwa wątki są tworzone zgodnie z głównymi funkcjami, tworzone są 2 wątki, ale pierwszy śpi przez 5 sekund po uzyskaniu zamka. Więc drugi wątek nie jest wprowadzany, gdy jest wywoływany. Wejdzie po 5-2 sekund, kiedy zostanie wywołany.
Sem_post będzie działał po funkcji snu; sem_post będzie działał i wyświetli pełny komunikat o stanie. W programie głównym semafor jest najpierw zainicjowany, a następnie oba wątki są tworzone za pomocą pThread. Używamy funkcji pthread_join, aby dołączyć do wątków. A na koniec semafory są zniszczone.
Zapisz plik z rozszerzeniem .C; Kod zostanie skompilowany, a wykonanie zostanie zakończone. Po wykonaniu zobaczysz, że pierwsza wiadomość jest wyświetlana, a następnie wykonanie kilku sekund, ponieważ zapewniliśmy funkcję snu z 5 sekundami, więc po tym czasie wyświetlany jest druga wiadomość dla pierwszego wątku.
Często wyświetlana jest pierwsza wiadomość dla drugiego wątku.
Druga wiadomość ponownie zajmie trochę czasu, aby kontynuować.
Przykład 2
Przed przejściem do drugiego przykładu, po pierwsze, musimy zrozumieć pojęcie problemu pisarza czytelnika. Załóżmy, że baza danych, którą chcesz podzielić między procesami, działa jednocześnie. Niektóre z tych procesów lub wątków mogą odczytać tylko bazę danych. Jednocześnie inni mogą chcieć zmodyfikować bazę danych. Dyskryminujemy między tymi dwoma, deklarując pierwszy jako czytelnik, a drugi jako pisarz. Jeśli dwóch czytelników uzyskuje dostęp do udostępnionych danych, nie spowoduje to żadnego efektu.
Aby zminimalizować występowanie tego rodzaju trudności, musimy pomóc pisarzom w dostępie do wspólnej bazy danych. Ten problem jest zsynchronizowany i znany jako problem z napisem czytelników.
Istnieje wiele odmian tego problemu. Pierwszy dotyczy problemu, że żaden czytelnik nie będzie czekał, chyba że pisarz użyje udostępnianych obiektów.
Ten program stanowi rozwiązanie dla pierwszego problemu z pisarzem czytnika. W tym kodzie źródłowym C użyliśmy 10 czytników i 5 procedur do zademonstrowania rozwiązania. Pierwsze dwa liczniki są podejmowane, które są określane jako zero. Nie czytnik identyfikuje liczbę czytelnika. Przechodząc w kierunku funkcji pisarza, używane są tutaj dwie funkcje semafora, pierwsza to oczekiwanie, a ten drugi to post. To wyświetli numer pisarza.
Po funkcji pisarza funkcja czytnika jest tutaj zadeklarowana. Pisarz zmodyfikuje bazę danych, aby czytelnik nie mógł wprowadzić ani zmienić niczego nabytych za pomocą zamka.
# Pthread_mutex_lock (& mutex);
Liczba nie czytelników jest następnie zwiększana. Tutaj nakłada się kontrola IF-STATEMENT. Jeśli wartość wynosi 1, oznacza to, że jest to pierwszy czytelnik, aby pisarz został zablokowany. Jeśli reader wynosi 0, po sprawdzeniu, oznacza to, że jest to ostatni czytelnik, więc pozwolimy teraz pisarzowi na modyfikację.
# Pthread_mutex_unlock (& mutex);
Przejdziemy do programu głównego zarówno po funkcji czytelnika, jak i pisarza. Tutaj zainicjowaliśmy 10 czytelników i 5 pisarzy. Funkcja SEM_INIT zainicjuje semafor. Do pętli są tu używane osobno zarówno dla czytelników, jak i pisarzy. Pthread_create utworzy funkcje odczytu i zapisu. Ponadto pthread_join dołączy do wątków. Każdy dla pętli użyje tego połączenia 5 razy w celu pisarza, a następnie 10 razy w celu czytelnika.
A na koniec semafor jest odpowiednio zniszczony po użyciu. Skompiluj kod, a następnie wykonaj go. Zobaczysz, że liczby losowe dla czytnika są generowane w 10 rozmiarach tablic z liczbą 1. A dla pisarza 5 liczb jest modyfikowanych.
Wniosek
Artykuł „SEM_INIT” jest funkcją używaną przez semafory w procesie wielowy w celu ustalenia priorytetów zadań występujących jednocześnie. Istnieje wiele innych funkcji związanych z semaforami, również omówiono tutaj. Wyjaśniliśmy dwa elementarne przykłady do rozwinięcia wykorzystania SEM_INIT w funkcjach i innych cechach.