0% found this document useful (0 votes)
17 views39 pages

Os Report

Uploaded by

nissy jessilyn
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views39 pages

Os Report

Uploaded by

nissy jessilyn
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 39

Project Based Learning (PBL) Report

for the course

Operating System(20CS22003)

ELECTIONS PROCESS USING DINNING PHILOSPHER WITH


SEMOPHERS
BACHELOR OF TECHNOLOGY
IN

COMPUTER SCIENCE AND ENGINEERING

By
P. Raziya(22R11A05H1)
Sk. Sania(22R11A05H6)
G. Sreeja(23R15A0517)
Under the guidance of Dr. K. Krishna Jyothi

Department of Computer Science and Engineering

Accredited by NBA

Geethanjali College of Engineering and Technology

(UGC Autonomous)

(Affiliated to J.N.T.U.H, Approved by AICTE, New Delhi)

Cheeryal (V), Keesara (M), Medchal.Dist.-501 301.

1
TABLE OF CONTENTS

S.No. Contents Page No

1 3
Abstract

2 4
Acknowledgement

3 5
Purpose of study

4 Introduction 6

5 Problem Statement 7

6 System Configuration 13

7 System Architecture 14

8 Proposed Solution 16

9 Implementation 17

10 Screen Short 21

11 Application 23

12 Implementation 25

13 Screen Short 28

14 Conclusion 35

15 Bibliography 36

ABSTRACT

2
The dining philosopher’s problem is a classical synchronization challenge in computer

science, illustrating the complexities of allocating shared resources without causing deadlock

or resource starvation. This report presents a novel approach to simulating the dining

philosopher’s problem using semaphores within the context of an election process. By

mapping the philosophers to election candidates and the forks to critical voting resources, we

explore how semaphore-based synchronization mechanisms can be employed to manage

concurrent access effectively. The simulation aims to ensure fair resource allocation, prevent

deadlocks, and maintain system liveness, reflecting the intricacies of real-world electoral

processes. Through this simulation, we demonstrate how semaphore operations—wait (P)

and signal (V)—can orchestrate complex interactions among multiple candidates, ensuring

orderly voting and resource distribution. The results provide insights into the effectiveness of

semaphore-based synchronization in managing concurrent processes and highlight potential

improvements for real-world applications in distributed systems and multi-

agent environments.

3
ACKNOWLEDGEMENT

We would like to acknowledge and give my warmest thanks to our faculty “Dr K Krishna

Jyothi” mam who made this work possible. Their guidance and advice carried us through all

the stages of writing our project. We would also like to thank our classmates for letting our

defence be an enjoyable moment, and for your brilliant comments and suggestions, thanks to

you. We would also like to give special thanks to our families as a whole for their continuous

support and understanding when undertaking my research and writing my project and

providing the required equipment. The project would not have been successful without their

cooperation and inputs.

4
PURPOSE OF STUDY

The primary purpose of this study is to explore the application of semaphore-based

synchronization techniques by simulating the dining philosopher’s problem within the

context of an election process. By mapping philosophers to election candidates and forks to

critical voting resources, this study aims to demonstrate how semaphores can effectively

manage concurrent access to shared resources. The simulation seeks to prevent common

issues such as deadlock and resource starvation, ensuring that all candidates can access

voting resources fairly and efficiently. This approach provides a practical illustration of

semaphore utilization in managing complex interactions and maintaining system liveness in a

competitive environment. Additionally, this study aims to bridge theoretical concepts with

real-world scenarios, enhancing the understanding of concurrency issues in distributed

systems. By modelling an election process, the study highlights the relevance and

applicability of synchronization mechanisms in practical settings. The insights gained are

intended to inform the design and implementation of robust systems, offering a foundational

framework for future research. Ultimately, the study emphasizes the practical implications of

semaphore-based synchronization, showcasing its potential to enhance the efficiency and

reliability of concurrent systems across various domains

5
INTRODUCTION

The dining philosopher’s problem, a classic synchronization issue in computer science,

exemplifies the challenges of resource allocation and process coordination in concurrent

systems. Traditionally, this problem involves a set of philosophers who alternately think and

eat, requiring access to shared forks. The core challenge is to design a protocol that allows

the philosophers to share resources without causing deadlock or starvation. This problem

serves as a powerful metaphor for various real-world scenarios where multiple entities vie

for limited resources.

In this report, we extend the dining philosophers problem to simulate an election process,

using semaphores as the synchronization mechanism. Here, the philosophers are analogous

to election candidates, and the forks represent critical voting resources. This simulation aims

to explore how semaphore-based synchronization can effectively manage concurrent access

to shared resources in a competitive environment. By implementing semaphore operations

such as wait (P) and signal (V), we strive to ensure fair resource allocation, prevent

deadlocks, and maintain system liveness. This study not only provides a practical

demonstration of semaphores but also highlights their relevance and applicability in real-

world scenarios, particularly in distributed systems and multi-agent environments.

6
PROBLEM STATEMENT

The dining philosopher’s problem is a classic example in computer science that deals with

how multiple people (philosophers) can share a limited number of resources (forks) without

running into issues like deadlock or unfair resource distribution. This problem helps us

understand how to manage resource sharing in systems where many processes run at the

same time. Can see the problem from figure 2 ,3,4,5. How it runs as infinity loops.

In this study, from fig1: we adapt the dining philosopher’s problem to simulate an election

process. Here, the philosophers represent election candidates, and the forks are the critical

voting resources they need. The main challenge is to create a system using semaphores (a

tool for managing resource access) that ensures each candidate gets a fair chance to access

the voting resources without causing deadlock or any candidate being unfairly blocked from

accessing resources. This adapted problem aims to find practical solutions for managing

shared resources in real-world scenarios, ensuring smooth and fair operations.

7
8
Fig1: the seating arrangement of philosophers

Problem Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM_PHILOSOPHERS 5

sem_t forks [NUM_PHILOSOPHERS];


sem_t room; // Semaphore to limit the number of philosophers accessing forks at the same
time

void *philosopher (void *num) {


int id = *(int *) num;

while (1) {
printf ("Philosopher %d is thinking\n", id);
sleep (1);

sem_wait(&room); // Try to enter the room

// Pick up left fork


sem_wait(&forks[id]);
printf ("Philosopher %d picked up fork %d (left)\n", id, id);
// Pick up right fork
sem_wait (&forks [(id + 1) % NUM_PHILOSOPHERS]);

9
printf ("Philosopher %d picked up fork %d (right)\n", id, (id + 1) %
NUM_PHILOSOPHERS);

// Eating

printf ("Philosopher %d is eating\n", id);


sleep (1);

// Put down right fork


sem_post (&forks [(id + 1) % NUM_PHILOSOPHERS]);
printf ("Philosopher %d put down fork %d (right)\n", id, (id + 1) %
NUM_PHILOSOPHERS);

// Put down left fork


sem_post(&forks[id]);
printf("Philosopher %d put down fork %d (left)\n", id, id);

sem_post(&room); // Leave the room

printf("Philosopher %d is thinking again\n", id);


}
return NULL;
}

int main() {
pthread_t philosophers[NUM_PHILOSOPHERS];

int ids[NUM_PHILOSOPHERS];

10
// Initialize semaphores

sem_init(&room, 0, NUM_PHILOSOPHERS - 1); // Allow up to NUM_PHILOSOPHERS-


1 philosophers to enter room
int i;
for (i = 0; i < NUM_PHILOSOPHERS; i++) {
sem_init(&forks[i], 0, 1);
}

// Create philosopher threads


for (i = 0; i < NUM_PHILOSOPHERS; i++) {
ids[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &ids[i]);
}

// Wait for philosopher threads to finish (they never will in this example)
for ( i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosophers[i], NULL);
}

// Destroy semaphores
for ( i = 0; i < NUM_PHILOSOPHERS; i++) {
sem_destroy(&forks[i]);
}
sem_destroy(&room);
return 0;
}
11
SCREENSHORT

Fig2: this is the out of the problem which runs in infinity loop

12
Fig3: this is the continues repetition after the single turn.

Fig4: infinity loop running after 15th notation

13
Fig5: the output does not end

SYSTEM CONFIGURATION

Hardware System Configuration


Component Specification

Processor Core i3 1005G1

Speed 4.40 GHz

RAM 4 GB

Hard Disk 1 TB (5400 rpm 2.5" SATA Hard Drive)

Keyboard Dell Inspiring Keyboard

Mouse Two or three button mouse

14
Software System Configuration

Component Specification

Operating System Windows 10 Home

Application Server Tomcat 5.0/6.x

Front End C Programming

Scripts C-Script

Server-Side Script C

15
SYSTEM ARTCHITECTURE

ASUMING A SITUATION:
Imagine a small town with five candidates running for office. Each candidate needs to gather

signatures from five different voting districts to qualify for the election. There are only five

signature collectors (one for each district), and each candidate can only work with one

collector at a time.

In the traditional dining philosopher’s problem, the candidates (philosophers) would need to

pick up two forks to eat, but in our adapted problem, they need to work with one signature

collector at a time. If two candidates try to get a signature from the same collector at the

same time, neither can proceed, leading to a deadlock. We can see the flow of System by

Fig6.

To solve this, we use semaphores. Each signature collector is protected by a semaphore that

ensures only one candidate can access the collector at a time. When a candidate wants to get

a signature, they perform a "wait" operation on the semaphore. If the semaphore is available,

the candidate proceeds. If not, the candidate waits until the collector is free. After getting the

signature, the candidate performs a "signal" operation to release the semaphore, making the

collector available for the next candidate.

This way, we ensure that all candidates get their turn to gather signatures without any two

candidates blocking each other, preventing deadlock and ensuring fair access to the voting

resources.

16
FLOW OF THE SYSTEM

Fig6: this is the flow of our proposed solution and can see the processes how each
fellow philosopher is Limited by 3.

17
PROPOSED SOLUTION

The code begins by defining constants for the number of philosophers (N) and their states

(THINKING, HUNGRY, EATING). It also defines arrays to store the state of each

philosopher, their IDs (ph. il), and the number of times each philosopher has eaten

(eat_count).By fig7,8,9 we can assume the structure and output of the philosopher’s.

Semaphores mutex and S[N] are declared. mutex is used to ensure mutual exclusion when

accessing shared resources, and S[N] is used to synchronize the philosophers.

test () function: This function checks if a philosopher can start eating. If a philosopher is

hungry and its neighbors are not eating, it changes its state to eating and signals that it can

start eating by posting to its semaphore.

take_fork() function: This function is called when a philosopher wants to eat. It sets the

philosopher's state to hungry and then tries to eat by calling test(). After that, it waits until it

can start eating by waiting on its semaphore.

put_fork () function: This function is called when a philosopher finish eating. It sets the

philosopher's state to thinking, increments it eat count, and then calls test () for its

neighbours.

philosopher () function: This function represents the behaviour of a philosopher. It keeps

running in a loop until the philosopher has eaten EAT_LIMIT times. In each iteration, it

alternates between thinking, taking forks, eating, and putting forks down.

18
main () function: It initializes semaphores, creates threads for each philosopher, and then

waits for all threads to finish.

IMPLEMENTATION
Solution Code:
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>

#define N 5
#define THINKING 2
#define HUNGRY 1
#define EATING 0
#define LEFT (phnum + 4) % N
#define RIGHT (phnum + 1) % N
#define EAT_LIMIT 3 // Each philosopher eats 3 times

int state[N];
int phil[N] = {0, 1, 2, 3, 4};
int eat_count[N] = {0}; // Counter for the number of times each philosopher has eaten

sem_t mutex;
sem_t S[N];

void test(int phnum)


{

19
if (state[phnum] == HUNGRY && state[LEFT] != EATING && state[RIGHT] !=
EATING)
}

state[phnum] = EATING;
sleep(2);
printf("Philosopher %d takes fork %d and %d\n", phnum + 1, LEFT + 1, phnum + 1);
printf("Philosopher %d is Eating\n", phnum + 1);
sem_post(&S[phnum]);
}
}
void take_fork(int phnum)
{
sem_wait(&mutex);
state[phnum] = HUNGRY;
printf("Philosopher %d is Hungry\n", phnum + 1);
test(phnum);
sem_post(&mutex);
sem_wait(&S[phnum]);
sleep(1);
}

void put_fork(int phnum)


{
sem_wait(&mutex);
state[phnum] = THINKING;

20
printf("Philosopher %d putting fork %d and %d down\n", phnum + 1, LEFT + 1, phnum +
1);
printf("Philosopher %d is thinking\n", phnum + 1);

eat_count[phnum]++;
test(LEFT);
test(RIGHT);
sem_post(&mutex);
}

void *philosopher(void *num)


{
int *i = num;
while(eat_count[*i] < EAT_LIMIT)
{
sleep(1);
take_fork(*i);
sleep(0);
put_fork(*i);
}
return NULL;
}
int main()
{
int i;
pthread_t thread_id[N];
sem_init(&mutex, 0, 1);
for(i = 0; i < N; i++)
21
sem_init(&S[i], 0, 0);

for(i = 0; i < N; i++)


{
pthread_create(&thread_id[i], NULL, philosopher, &phil[i]);
printf("Philosopher %d is thinking\n", i + 1);
}
for(i = 0; i < N; i++)
{
pthread_join(thread_id[i], NULL);
printf("All philosophers have finished eating.\n");
return 0;
}

22
SCREENSHORT

Fig7: The proposed solution in which each philosopher eats 3 times consider as per day.

Fig 8: In this each philosopher Starts eating 2nd time


23
Fig9: In This the Philosopher starts eating 3rd i.e. is last time

24
APPLICATIONS:

The Dining Philosophers problem illustrates resource sharing and deadlock prevention in

concurrent systems. Its principles are applied in various real-world scenarios:

Operating Systems: Manages resource allocation and concurrency control using semaphores

and mutexes to prevent deadlocks and ensure fair access to resources like files and memory.

Database Systems: Handles concurrent transactions with locking mechanisms to maintain

data consistency, using strategies to detect and prevent deadlocks.

Networking and Communication Protocols: Allocates bandwidth and manages resource

reservations efficiently to avoid network contention and ensure smooth data transmission.

Manufacturing Systems: Coordinates tool sharing and production line synchronization to

prevent resource contention and ensure smooth operation of automated systems.

Synchronizes threads to avoid race conditions and manage shared resources effectively,

ensuring thread safety and optimal resource usage.

Real-Time Systems: Schedules tasks and handles priority inversion to meet deadlines and

prevent conflicts over shared resources, ensuring timely task execution.

Election Algorithms: In distributed systems, election algorithms ensure that a single process

(like a leader or coordinator) is selected from a group of processes to avoid conflicts and

manage resources efficiently. Techniques from the Dining Philosophers problem help in

designing these algorithms to avoid deadlocks and ensure fair election processes.

25
These applications use semaphore-based synchronization techniques to achieve efficient and

fair resource allocation, preventing deadlocks and ensuring reliable operation. From fig10,11

you can consider people voting as 1st type semaphores.

A semaphore typically consists of a non-negative integer counter and two atomic operations:

wait (also known as P or down) and signal (also known as V or up). The wait operation

decrements the semaphore's counter and blocks the calling thread if the counter becomes

negative, while the signal operation increments the counter and unblocks a waiting thread if

necessary.

In conclusion, from figure 12,13,14 we can see the end of voting and consider the all

semaphores done and results are announced. The Dining Philosophers problem effectively

demonstrates the complexities of managing concurrent resource allocation and the potential

pitfalls of deadlock and resource contention in a shared environment. By utilizing

semaphores to control access to shared resources (forks), we can ensure mutual exclusion

and prevent deadlock, thereby allowing multiple processes (philosophers) to operate

concurrently without conflict. This approach not only illustrates key concepts in concurrent

programming but also provides a practical framework for addressing similar synchronization

challenges in real-world applications.

26
IMPLEMENTATION

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM_CANDIDATES 5
sem_t booths[NUM_CANDIDATES];
sem_t room; // Semaphore to limit the number of candidates accessing booths at the same
time
void* candidate(void* num) {
int id = *(int*)num;
while (1) {
printf("Candidate %d is preparing to vote\n", id);
sleep(1);
sem_wait(&room); // Try to enter the room
// Pick up left booth
sem_wait(&booths[id]);
printf("Candidate %d picked up booth %d (left)\n", id, id);
// Pick up right booth
sem_wait(&booths[(id + 1) % NUM_CANDIDATES]);
printf("Candidate %d picked up booth %d (right)\n", id, (id + 1) %
NUM_CANDIDATES);
// Voting
printf("Candidate %d is voting\n", id);
sleep(1);
// Put down right booth
sem_post(&booths[(id + 1) % NUM_CANDIDATES]);
27
printf("Candidate %d put down booth %d (right)\n", id, (id + 1) % NUM_CANDIDATES);

// Put down left booth


sem_post(&booths[id]);
printf("Candidate %d put down booth %d (left)\n", id, id);

sem_post(&room); // Leave the room

printf("Candidate %d is done voting and preparing again\n", id);


}
return NULL;
}

int main() {
pthread_t candidates[NUM_CANDIDATES];
int ids[NUM_CANDIDATES];
int i;
// Initialize semaphores
sem_init(&room, 0, NUM_CANDIDATES - 1); // Allow up to NUM_CANDIDATES-1
candidates to enter room
for (i = 0; i < NUM_CANDIDATES; i++) {
sem_init(&booths[i], 0, 1);
}

28
// Create candidate threads
for (i = 0; i < NUM_CANDIDATES; i++) {
ids[i] = i;
pthread_create(&candidates[i], NULL, candidate, &ids[i]);
}

// Wait for candidate threads to finish (they never will in this example)
for (i = 0; i < NUM_CANDIDATES; i++) {
pthread_join(candidates[i], NULL);
}

// Destroy semaphores
for (i = 0; i < NUM_CANDIDATES; i++) {
sem_destroy(&booths[i]);
}
sem_destroy(&room);

return 0;
}

29
SCREENSHORT

Fig10: In this 1st 3 areas the voters started their voting & leaving the booth.

Fig11: In this next 4 booth voters are voting in the booth came (ri8) and left

30
Fig12: In this the all the candidates of all the areas came and voted in there
Respective booth and voting are completed.

31
// Continues………………
#define NUM_POLITICIANS 5
#define NUM_AREAS 10

sem_t booths[NUM_AREAS]; // Semaphores for voting booths in different areas


sem_t room; // Semaphore to limit the number of candidates voting at the same time

int votes[NUM_POLITICIANS] = {0}; // Votes received by each candidate


pthread_mutex_t vote_lock; // Mutex to protect vote counting

void* politician(void* num) {


int id = *(int*)num;

printf("Politician %d is preparing to vote\n", id);


sleep(1);

sem_wait(&room); // Try to enter the voting room

int area = rand() % NUM_AREAS; // Randomly choose an area for the politician to vote
sem_wait(&booths[area]);

printf("Politician %d entered booth in area %d\n", id, area);


// Voting
printf("Politician %d is voting in area %d\n", id, area);
sleep(1);

32
// Lock the votes array and update the vote count
pthread_mutex_lock(&vote_lock);
votes[id]++; // Increment the vote count for this politician
pthread_mutex_unlock(&vote_lock);

// Leave the booth


sem_post(&booths[area]);
printf("Politician %d left booth in area %d\n", id, area);

sem_post(&room); // Leave the voting room

printf("Politician %d is done voting and preparing again\n", id);

// Exit after casting a vote for simplicity in this example


return NULL;
}

int main() {
pthread_t politicians[NUM_POLITICIANS];
int ids[NUM_POLITICIANS];
int i;
// Initialize semaphores and mutex

sem_init(&room, 0, NUM_AREAS); // Allow up to NUM_AREAS politicians to vote


simultaneously
}

33
for (i = 0; i < NUM_AREAS; i++) {
sem_init(&booths[i], 0, 1);

pthread_mutex_init(&vote_lock, NULL);

// Create politician threads


for ( i = 0; i < NUM_POLITICIANS; i++) {
ids[i] = i;
pthread_create(&politicians[i], NULL, politician, &ids[i]);
}

// Wait for politician threads to finish


for ( i = 0; i < NUM_POLITICIANS; i++) {
pthread_join(politicians[i], NULL);
}

// Assign unique votes to each politician for demonstration


for ( i = 0; i < NUM_POLITICIANS; i++) {
votes[i] = rand() % 100 + 1; // Random votes between 1 and 100
}

// Determine the winner


int max_votes = 0;
int winner = -1;
for ( i = 0; i < NUM_POLITICIANS; i++) {

34
if (votes[i] > max_votes) {
max_votes = votes[i];
winner = i;
}
}

// Print results in tabular form


printf("\nElection Results:\n");
printf("+----------------+---------------+\n");
printf("| Politician ID | Votes Received|\n");
printf("+----------------+---------------+\n");
for ( i = 0; i < NUM_POLITICIANS; i++) {
printf("| %d | %d |\n", i, votes[i]);
}
printf("+----------------+---------------+\n");
printf("The winner is Politician %d with %d votes.\n", winner, max_votes);

// Destroy semaphores and mutex


for (i = 0; i < NUM_AREAS; i++) {
sem_destroy(&booths[i]);
}
sem_destroy(&room);
pthread_mutex_destroy(&vote_lock);
return 0;
}

35
SCREENSHORT

Fig13: Here the political Candidates are casting votes

Fig14: Here we are declaring the results based on voters and candidates voting.

36
CONCLUSION

Hence, we concluded that the use of semaphores and mutexes for managing resource

allocation and synchronization in concurrent systems, applied to voting processes. In the first

example, candidates simulate the Dining Philosophers problem, using semaphores to ensure

that only a limited number can enter the voting room simultaneously and manage booth

access to avoid deadlock. The second example involves politicians voting in multiple areas,

with semaphores controlling booth entry and a mutex ensuring accurate vote tallying without

race conditions. These examples emphasize the importance of efficient resource

management, preventing contention, and ensuring fair access. The practical implementation

includes random vote assignments and tabular election results, demonstrating the techniques'

relevance in real-world scenarios like operating systems, database management, and

distributed systems. By employing synchronization mechanisms, the codes ensure orderly

operation and reliable coordination of shared resources, critical for system

stability and fairness.

37
BIBILOGRAHY

 www.google.com

 www.wikipedia.com

 www.gcet.library.com

38

You might also like