Perché i semafori sono usati?
Durante l'utilizzo dei thread, incontriamo diverse questioni condizionali che coinvolgono le condizioni di razza. Ciò si verifica quando due o più thread necessitano degli stessi dati o informazioni contemporaneamente che causano conflitti. Quindi, per evitare questo tipo di situazione contrastante, usiamo i semafori. Esistono tre tipi principali di semafori. Uno è un semaforo binario e un altro è un semaforo di conteggio.
Utilizziamo diverse funzioni nell'intervallo di semaforo come SEM_WAIT, SEM_POST e SEM_Init. Sem_init è l'argomento in esame ulteriormente in questo articolo.
Sem_init
Come abbiamo discusso in precedenza, per inizializzare il semaforo nei thread, utilizziamo la funzione SEM_init. Qui utilizziamo un flag o un banner che identifica la condivisione di semaforo con fork ().
Sintassi
# sem
Sem: Questa funzione aiuta il semaforo ad essere in uno stato pronto.
Pshared: Questo argomento dei parametri è fondamentale nella dichiarazione di semaforo. In quanto determina lo stato del semaforo di nuova inizializzazione. Se dovrebbe essere condiviso o meno tra i processi o i thread. Se il valore è diverso da zero, significa che il semaforo è condiviso tra due o più processi e se il valore è zero, allora significa che il semaforo è condiviso tra i thread.
Valore: Specifica il valore che deve essere assegnato al semaforo appena creato che viene assegnato inizialmente.
Implementazione di sem_init
Per eseguire semafori nel programma C, abbiamo bisogno di un compilatore GCC. Ma questo non è sufficiente. "-LpThread" viene utilizzato per eseguire il codice. 'UN.C 'è il nome del file. Un'altra cosa è che qui usiamo '.fuori "con il nome del file invece di utilizzare il file in modo indipendente.
Esempio 1
Innanzitutto, aggiungiamo due librerie con semafori e pThread per indulgere all'uso di pacchetti C. Come SEM_init, altri semafori sono usati in questo programma; Qui, ne discuteremo.
Sem_wait ()
Questa funzione viene utilizzata per tenere un semaforo o per continuare ad aspettare. Se il valore fornito al semaforo è negativo, la chiamata è bloccata e il ciclo è chiuso. Mentre qualsiasi altro thread, quando viene chiamato, i semafori bloccati vengono risvegliati.
Sem_post ()
Il metodo SEM_POST viene utilizzato per aumentare il valore del semaforo. Il valore viene incrementato da sem_post quando viene chiamato.
Sem_destroy ()
Se vogliamo distruggere il semaforo, utilizziamo il metodo SEM_DESTROY. Ora, concentrati sul codice sorgente fornito qui. Innanzitutto, la funzione "Aspetta" viene utilizzata qui. Farà aspettare prima il thread in modo che gli altri possano eseguire un'attività. Viene visualizzato un messaggio che il thread viene inserito durante la chiamata della funzione. Successivamente, una funzione di "sonno" è chiamata per 5 secondi.
Vengono creati due thread in base alle funzioni principali, vengono creati 2 thread, ma il primo dorme per 5 secondi dopo l'acquisizione del blocco. Quindi il secondo thread non viene inserito quando viene chiamato. Entrerà dopo 5-2 secondi quando viene chiamato.
SEM_Post funzionerà dopo la funzione di sonno; sem_post funzionerà e mostrerà un messaggio di stato completo. Nel programma principale, il semaforo viene inizializzato per primo, quindi entrambi i thread vengono creati utilizzando PThread. Usiamo la funzione pThread_join per unire i thread. E alla fine, i semafori vengono distrutti.
Salva il file con l'estensione di .C; il codice verrà compilato e l'esecuzione verrà eseguita. Durante l'esecuzione, vedrai che viene visualizzato il primo messaggio, quindi per completare alcuni secondi, poiché abbiamo fornito alla funzione di sonno con 5 secondi, quindi dopo quel tempo viene visualizzato il secondo messaggio per il primo thread.
Spesso viene visualizzato il primo messaggio per il secondo thread.
Il secondo messaggio richiederà di nuovo il tempo per procedere.
Esempio 2
Prima di spostarsi verso il secondo esempio, in primo luogo, dobbiamo comprendere il concetto del problema dello scrittore del lettore. Supponiamo che un database che desideri condividere tra i processi sia contemporaneamente. Alcuni di questi processi o thread possono leggere solo il database. Allo stesso tempo, ad altri potrebbe piacere modificare il database. Discriminiamo tra questi due dichiarando il primo come lettore e il secondo come scrittore. Se due lettori accedono ai dati condivisi, non causerà alcun effetto.
Per ridurre al minimo il verificarsi di questo tipo di difficoltà, dobbiamo aiutare gli scrittori ad accedere al database condiviso per scrivere in esso. Questo problema è sincronizzato e noto come problema dei lettori.
Ci sono molte varianti in questo problema. Il primo affronta il problema che nessun lettore aspetterà a meno che uno scrittore non usi oggetti condivisi.
Questo programma fornisce la soluzione per il primo problema del lettore-scrittore. In questo codice sorgente C, abbiamo usato 10 lettori e 5 procedure per dimostrare la soluzione. I primi due contatori vengono presi che vengono indicati come zero. Il non direttore identifica il numero del lettore. Muovendosi verso la funzione dello scrittore, qui vengono utilizzate due funzioni di semaforo, la prima è l'attesa e quest'ultima è il post. Questo visualizzerà il numero dello scrittore.
Dopo la funzione Writer, la funzione del lettore viene dichiarata qui. Lo scrittore modificherà il database in modo che il lettore non possa inserire o modificare qualsiasi cosa acquisita da un blocco.
# PThread_mutex_lock (& mutex);
Il conteggio non dei non leader viene quindi incrementato. Qui viene applicato un controllo di If-Statement. Se il valore è 1, significa che è il primo lettore in modo che lo scrittore venga bloccato. Se il non direttore è 0, dopo il controllo, significa che è l'ultimo lettore, quindi ora consentiremo allo scrittore per la modifica.
# PThread_mutex_unlock (& mutex);
Ci sposteremo verso il programma principale dopo la funzione del lettore e dello scrittore. Qui abbiamo inizializzato 10 lettori e 5 scrittori. La funzione sem_init inizializzerà il semaforo. Per i loop vengono utilizzati qui separatamente sia per i lettori che per gli scrittori. Pthread_create creerà le funzioni di lettura e scrittura. Inoltre, pThread_join si unirà ai thread. Ciascuno per loop utilizzerà questo giunto 5 volte a scopo di scrittore e quindi 10 volte a scopo del lettore.
E alla fine, il semaforo viene distrutto rispettivamente dopo l'uso. Compilare il codice e quindi eseguirlo. Vedrai che i numeri casuali per il lettore sono generati entro 10 dimensioni dell'array con il conteggio 1. E per lo scrittore, 5 numeri vengono modificati.
Conclusione
L'articolo 'sem_init' è una funzione utilizzata dai semafori nel processo multithreading per dare la priorità alle attività che si verificano contemporaneamente. Ci sono molte altre funzioni relative ai semafori, anche qui discussi. Abbiamo spiegato due esempi elementari per elaborare l'uso di sem_init nelle funzioni e altre funzionalità.