Blokady typu spinlock są użyteczne gdy proces nie musi długo czekać. Gdy czas oczekiwania jest długi dużo lepiej używać semaforów.
Pod blokadą typu spinlock należy przebywać jak najkrócej, ponieważ wstrzymuje ona pracę innych procesów w sposób nieefektywny - proces wykonując spinlock_lock marnuje czas procesora.
Semafor:
Inicjalizacja.
Zdobycie blokady.
Zwolnienie blokady.
struct semaphore{ struct task *queue; unsigned int value; }; typedef struct semaphore semaphore_t; void semaphore_init(semaphore *sem) { sem->queue = 0; sem->value = 1; } void semaphore_lock(semaphore_t *sem); void semaphore_unlock(semaphore_t *sem);
Rozważmy najpierw rozwiązanie, w którym blokowane są przerwania.
void semaphore_lock(semaphore_t *sem) { disable_interrupts(); if (sem->value==1) { sem->value=0; } else { add_last(sem->queue, current); remove(run_queue, current); scheduler(); } restore_interrupts(); } void semaphore_unlock(semaphore_t *sem) { disable_interrupts(); if (empty(sem->queue)) { sem->value = 1; } else { struct task *next = remove_first(sem->queue); add_last(run_queue, next); } restore_interrupts(); }
To rozwiązanie jest poprawne na jednoprocesorowej maszynie. Na wieloprocesorowej maszynie nie jest poprawne, gdyż nie zapewnia żadnej synchronizacji między procesorami.