Experiment 4
Experiment 4
Aim:
Program to implement Mutual Exclusion to access a shared file using centralized
algorithm. Simulate the process and coordinator as different processes. Also design how
to handle a scenario when a process having a resource crashes.
Number of processes: minimum 5.
Number of resources: minimum 2 files
Description:
In centralized algorithm one process is elected as the coordinator which may be the
machine. Whenever a process wants to enter a critical region, it sends a request message to
the coordinator stating which critical region it wants to enter and asking for permission. If
no other process is currently in that critical region, the coordinator sends back a reply
granting permission). When the reply arrives, the requesting process enters the critical
region. When another process asks for permission to enter the same critical region. Now
the coordinator knows that a different process is already in the critical region, so it cannot
grant permission. The coordinator just refrains from replying, thus blocking process 2,
which is waiting for a reply or it could send a reply ‘permission denied.’ When process 1
exits the critical region, it sends a message to the coordinator releasing its exclusive access.
The coordinator takes the first item off the queue of deferred requests and sends that
process a grant message. If the process was still blocked it unblocks and enters the critical
region. If an explicit message has already been sent denying permission, the process will
have to poll for incoming traffic or block later. When it sees the grant, it can enter the
critical region.
Code:
Client.c
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>
typedef struct resources
{
int A; char B; int C; char D; char E;
}resources;
int main()
{
struct sockaddr_in sa; // Socket address data structure
resources R;
int n, sockfd; // read and source
char buff[1025], obuff[256]; // buffer to store the read stream
int snded, rec;
else
printf("Socket created\n");
while (1)
{
snded = write(sockfd, "PING", 5);
if (snded > -1)
printf("SENT PING\n");
rec = read(sockfd, obuff, 256);
obuff[rec] = '\0';
if (strcmp(obuff, "PONG") == 0)
{
usleep(750);
FILE *f;
FILE *f2;
f = fopen("shared_mem.txt", "r");
fread(&R, sizeof(R), 1, f);
fclose(f);
f2 = fopen("shared2.txt", "r");
fread(&R, sizeof(R), 1, f2);
fclose(f2);
printf("Read %d, %d, %d, %d, %d from server\n", R.A, R.B, R.C, R.D, R.E);
R.A += 1;
R.B += 1;
R.C += 1;
R.D += 1;
R.E += 1;
f = fopen("shared_mem.txt", "w");
fwrite(&R, sizeof(R), 1, f);
fclose(f);
f = fopen("shared2.txt", "w");
fwrite(&R, sizeof(R), 1, f2);
fclose(f2);
printf("Got access to CS\n");
snded = write(sockfd, "DONE", 4);
printf("Freeing Lock\n");
break;
}
}
close(sockfd); // Closing the socket
return 0;
}
Controller.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
int main()
{
resources R, temp;
R.A = 1;
R.B = 2;
R.C = 3;
R.D = 4;
R.E = 5;
FILE *fle;
FILE *fle2;
fle = fopen("shared_mem.txt", "w");
fle2 = fopen("shared2.txt", "w");
fwrite(&R, sizeof(R), 1, fle);
fwrite(&R, sizeof(R), 1, fle2);
fclose(fle);
fclose(fle2);
struct sockaddr_in sa; // Socket address data structure
int opt = TRUE, addrlen;
int sockfd, clients[50];
char buff[256]; // Buffer to hold the out-going stream
int rec, i, sd, activity, new_sock, sended;
int max_sd;
int flag = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0); // New socket created
// Checking for valid socket
memset(clients, 0, sizeof(clients));
fd_set readfds;
if (sockfd < 0)
{
printf("Error in creating socket\n");
exit(0);
}
else
{
printf("Socket Created\n");
}
else
printf("Binded\n");
FD_SET(sockfd, &readfds);
max_sd = sockfd;
if (FD_ISSET(sockfd, &readfds))
{
if ((new_sock = accept(sockfd, (struct sockaddr *)NULL, NULL)) < 0)
perror("accept");
else
{
printf("New connection, sock fd %d\n", new_sock);
}
if (sended < 0)
perror("Send");
if (FD_ISSET(sd, &readfds))
{
FILE *fle;
fle = fopen("shared_mem.txt", "r");
fread(&temp, sizeof(temp), 1, fle);
fclose(fle);
FILE *fle2;
fle2 = fopen("shared2.txt", "r");
fread(&temp, sizeof(temp), 1, fle2);
fclose(fle2);
rec = read(sd, buff, 256);
if (rec == 0)
{
getpeername(sd, (struct sockaddr *)&sa, (socklen_t *)&sa);
printf("%d has disconnected unexpectedly with ip %s and port %d\n", sd,
inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
printf("recovering data\n");
FILE *fle;
fle = fopen("shared_mem.txt", "w+");
fwrite(&temp, sizeof(temp), 1, fle);
fclose(fle);
FILE *fle2;
fle2 = fopen("shared2.txt", "w+");
fwrite(&temp, sizeof(temp), 1, fle2);
fclose(fle2);
close(sd);
clients[i] = 0;
}
else
{
buff[rec] = '\0';
printf("recieved %s from %d\n", buff, sd);
FILE *fle2;
fle2 = fopen("shared2.txt", "r");
fread(&temp, sizeof(temp), 1, fle2);
printf("Read %d, %d, %d, %d, %d from %d\n", temp.A, temp.B, temp.C,
temp.D, temp.E, sd);
fclose(fle);
fclose(fle2);
clients[i] = 0;
close(sd);
break;
}
}
}
}
}
Centralised Algorithm is fair and requests are granted in the order in which they are received.
There is no starvation and is easy to implement and it has the disadvantage that the coordinator is
a single point of failure, the entire system may go down if it crashes.
Findings and Learnings:
1. We successfully implemented Centralized Mutual Exclusion.