Lab 09 - Synchronization
Lab 09 - Synchronization
BESE – 14AB
12th April 2025
The purpose of this lab is to introduce synchronization primitives like semaphores, mutexes, etc.
to produce the output as per requirement.
Objectives
This lab will enable you to use synchronization primitives programmatically and alter the output
as per requirements.
Tools/Software Requirement
Description
#include <pthread.h>
#include <stdio.h>
#define FIRST_ODD_NUM 1
#define FIRST_EVEN_NUM 2
#define MAX 10
int even_num_to_print;
even_num_to_print += 2;
CS330: Operating Systems Page 2
}
int odd_num_to_print;
odd_num_to_print += 2;
Above written code presents a program that uses two threads to print odd and even numbers from
1 to MAX (a macro defined in the code). Line 25 defines the main method, which is the starting
point for this program. Line 26 initializes two handles even_thread and odd_thread to represent
the two printing threads. On line 28 and 29, the main method starts even_thread and odd_thread
(asynchronously) and calls join for both threads to finish its execution. At this point, odd_thread
and even_thread have started their execution in parallel. The odd_thread is responsible for
printing odd numbers between FIRST_ODD_NUM and MAX—this thread prints 1, 3,5,7,9.
Tasks
a. Your first task is to compile and run this code on your system. The issue is that we have
no control over the order these numbers are printed on the console. For example, one
sample run of the program produces:
The output order varies because the two threads run concurrently without synchronization.
The operating system schedules them independently, leading to unpredictable interleaving of
their outputs. Since both threads access the console simultaneously, the final order depends
on thread execution timing.
b. Your second and main task here is to modify the source code and use synchronization
primitives available to you (semaphore and mutex) to produce the output in ascending
order.
Semaphore Implementation:
#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#define MAX 10
#define FIRST_ODD_NUM 1
#define FIRST_EVEN_NUM 2
sem_t sem_odd;
sem_t sem_even;
sem_wait(&sem_odd);
sem_post(&sem_even);
return NULL;
sem_wait(&sem_even);
sem_post(&sem_odd);
return NULL;
int main() {
// Initialize semaphores
printf("Semaphore Implementation\n");
pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_destroy(&sem_odd);
sem_destroy(&sem_even);
printf("\n");
return 0;
Output:
Mutex Implementation
#include <pthread.h>
#include <stdio.h>
#define MAX 10
while (1) {
pthread_mutex_lock(&lock);
pthread_cond_wait(&cond, &lock);
pthread_mutex_unlock(&lock);
break;
current++;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
return NULL;
while (1) {
pthread_mutex_lock(&lock);
pthread_cond_wait(&cond, &lock);
CS330: Operating Systems Page 7
}
pthread_mutex_unlock(&lock);
break;
current++;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
return NULL;
int main() {
printf("Mutex Implementation\n");
pthread_join(odd_thread, NULL);
pthread_join(even_thread, NULL);
printf("\n");
return 0;