0% found this document useful (0 votes)
6 views

LAB 5 - Semaphore Implementation

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

LAB 5 - Semaphore Implementation

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

LAB 5: Implementation of Semaphore

Semaphores are a synchronization primitive used in concurrent programming to control


access to a shared resource. They allow multiple threads or processes to coordinate their
access to shared resources by controlling the flow of execution based on the availability of
the resource.

1. What is a Semaphore?

A semaphore is a variable or abstract data type that is used for controlling access to a shared
resource by multiple processes or threads in a concurrent system. It maintains a count of the
available resources and provides operations to wait for a resource to become available (down
operation) and signal that a resource has been released (up operation).

2. Semaphore Operations:

 Wait (down) operation (sem_wait): Decrements the semaphore count by one. If the
count becomes negative, the calling thread or process is blocked until the count becomes
positive again.
 Signal (up) operation (sem_post): Increments the semaphore count by one, waking up
any threads or processes that are waiting for the semaphore.
3. Implementation of Semaphore:
 In C, semaphores are typically implemented using the POSIX semaphore API, which
provides functions for initializing, waiting on, and signaling semaphores. Here's a basic
implementation of a semaphore using POSIX threads and functions:
 This code demonstrates a simple example of using semaphores for thread synchronization
in a concurrent program.

Step 1: Write the C Code

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h> // For sleep function

#define NUM_THREADS 5

// Global semaphore
sem_t semaphore;
// Thread function
void *thread_func(void *arg) {
int tid = *(int *)arg; // Thread ID

// Print a message indicating the thread is waiting


printf("Thread %d is waiting...\n", tid);

// Wait on the semaphore


sem_wait(&semaphore);

// Print a message indicating the thread has entered the critical section
printf("Thread %d has entered the critical section.\n", tid);

// Simulate some work


sleep(1);

// Print a message indicating the thread is exiting the critical section


printf("Thread %d is exiting the critical section.\n", tid);

// Signal semaphore
sem_post(&semaphore);

pthread_exit(NULL);
}

int main() {
pthread_t threads[NUM_THREADS]; // Array to store thread IDs
int thread_ids[NUM_THREADS]; // Array to store thread IDs

// Initialize semaphore
if (sem_init(&semaphore, 0, 1) != 0) { // Initialize the semaphore with a value of 1
perror("Semaphore initialization failed");
exit(EXIT_FAILURE);
}

// Create threads
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i; // Assigning thread ID
if (pthread_create(&threads[i], NULL, thread_func, &thread_ids[i]) != 0) { // Create
threads
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
}

// Join threads
for (int i = 0; i < NUM_THREADS; i++) {
if (pthread_join(threads[i], NULL) != 0) { // Wait for threads to finish
perror("Thread join failed");
exit(EXIT_FAILURE);
}
}

// Destroy semaphore
sem_destroy(&semaphore);

return 0;
}
Step 2: Save the Code
Save the code above into a file named semaphore.c.
Step 3: Compile the Code
In the Cygwin terminal, navigate to the directory where you saved semaphore.c and run the
following command to compile it:
gcc -o semaphore semaphore.c -pthread
Step 4: Run the Executable
After successful compilation, you will find an executable named semaphore in the same
directory. Run it using the following command:
./semaphore
Step 5: Verify Output
You should see output from each thread as they enter and exit the critical section, controlled
by the semaphore.

4. Explanation of Code:

 We start by including necessary header files such as stdio.h, stdlib.h, pthread.h,


semaphore.h, and unistd.h.
 We define the number of threads to create (NUM_THREADS) and declare a global
semaphore variable semaphore.
 The thread_func function is the function executed by each thread. It simulates a critical
section by waiting on the semaphore, performing some work, and then releasing the
semaphore.
 In the main function, we initialize the semaphore using sem_init, create threads using
pthread_create, wait for threads to finish using pthread_join, and finally destroy the
semaphore using sem_destroy

You might also like