Site Tools


lst-semaphores

Code snippets: Semaphores

Basic synchronization

Two threads a() and b() alternate their execution regardless of the scheduler.

Output: abababababab...

Sem sa = 1, sb = 0;
 
void a() {
    while (true) {
        wait(sa);
        printf("a")
        signal(sb);
    }
}
 
void b() {
    while (true) {
        wait(sb);
        printf("b");
        signal(sa);
    }
}

Critical Section & Mutex

Threads a() and b() are not allowed to execute // ... CRITICAL SECTION ... at the same time.

The issue is resolved by using a mutex semaphore.

Sem mutex = 1;
 
void a() {
    while (true) {
        wait(mutex);
        //... CRITICAL SECTION ...
		signal(mutex);
        usleep(50);
    }
}
 
void b() {
    while (true) {
        wait(mutex);
        // ... CRITICAL SECTION ...
		signal(mutex);
        usleep(50);
    }
}

Producer & Consumer / Bounded Buffer

There is a global buffer of a bounded capacity $B$.

“Producers” produce and append data to the head. They are not allowed to put more items than $B$ in the buffer.

“Consumers” take and consume data from the buffer. They are not take data from the buffer if the buffer is empty.

The issue is resolved by using two synchronization semaphores full and empty and one mutex semaphore to guard the common buffer.

It is, however, possible to use two mutexes mutex_consumer and mutex_producer if the buffer is implemented in a way

#define B 10 /* buffer capacity */
 
Buffer buffer;
Sem mutex = 1;
Sem full = B;
Sem empty = 0;
 
void producer(int id) {
    while (true) {
        Data data = produce_data();
 
        wait(full);
        wait(mutex);
 
        put_data(buffer, data)
 
        signal(mutex);
        signal(empty);
    }
}
void consumer(int id) {
    while (true) {
        wait(empty);
        wait(mutex);
 
        Data data = get_data(buffer);
 
        signal(mutex);
        signal(full);
 
        consume_data(data);
    }
}
lst-semaphores.txt · Last modified: by Ivan Janevski