Вы находитесь на странице: 1из 6

EXPERIMENT 5

AIM:
Program to implement Mutual Exclusion to share files using token based algorithm

Introduction and Theory:


Token Ring algorithm achieves mutual exclusion in a distributed system by creating a bus network of
processes. A logical ring is constructed with these processes and each process is assigned a position in
the ring. Each process knows who is next in line after itself. When the ring is initialized, process 0 is given
a token. The token circulates around the ring. When a process acquires the token from its neighbor, it
checks to see if it is attempting to enter a critical region. If so, the process enters the region, does all the
work it needs to, and leaves the region. After it has exited, it passes the token to the next process in the
ring. It is not allowed to enter the critical region again using the same token. If a process is handed the
token by its neighbor and is not interested in entering a critical region, it just passes the token along to
the next process. • Advantages: o The correctness of this algorithm is evident. Only one process has the
token at any instant, so only one process can be in a CS o Since the token circulates among processes in
a well-defined order, starvation cannot occur. • Disadvantages o Once a process decides it wants to
enter a CS, at worst it will have to wait for every other process to enter and leave one critical region. o If
the token is ever lost, it must be regenerated. In fact, detecting that it is lost is difficult, since the
amount of time between successive appearances of the token on the network is not a constant. The fact
that the token has not been spotted for an hour does not mean that it has been lost; some process may
still be using it. o The algorithm also runs into trouble if a process crashes, but recovery is easier than in
the other cases. If we require a process receiving the token to acknowledge receipt, a dead process will
be detected when its neighbor tries to give it the token and fails. At that point the dead process can be
removed from the group, and the token holder can pass the token to the next member down the line

PROGRAM CODE:
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#define MAXLINE 1024

int create_connection(int PORT) {


int sockfd;
struct sockaddr_in servaddr;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
int optval = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&optval, sizeof(int));
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
if (bind(sockfd, (const struct sockaddr*)&servaddr,
sizeof(servaddr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
return sockfd;
}
void critical_section(int MY_PORT) {
printf("Entering the critical section\n");
sleep(5);
FILE* fp;
fp = fopen("common_token_ring.txt", "a");
fprintf(fp, "Written by process %d\n", MY_PORT);
fclose(fp);
}
int main(int argc, char* argv[]) {
int MY_PORT = atoi(argv[1]);
int NEXT_CLIENT_PORT = atoi(argv[2]);
int IS_INITIATOR = atoi(argv[3]);

char buffer[MAXLINE];
printf("Initialising the server at port %d.\n", MY_PORT);
int sockfd = create_connection(MY_PORT);

struct sockaddr_in next_client_addr, prev_client_addr;


int len, n;

char response[MAXLINE];
memset(&next_client_addr, 0, sizeof(next_client_addr));
next_client_addr.sin_family = AF_INET; // IPv4
next_client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
next_client_addr.sin_port = htons(NEXT_CLIENT_PORT);

if (IS_INITIATOR) {
critical_section(MY_PORT);
strcpy(response, "ACK");
printf("Printing %s to port %d. \n", response, NEXT_CLIENT_PORT);
int check = sendto(sockfd, (const char*)response, strlen(response), MSG_CONFIRM, (const
struct sockaddr*)&next_client_addr, sizeof(next_client_addr));

memset(&prev_client_addr, 0, sizeof(prev_client_addr));
n = recvfrom(sockfd, (char*)buffer, MAXLINE, MSG_WAITALL, (struct
sockaddr*)&prev_client_addr, &len);
buffer[n] = '\0';
if (!strcmp(buffer, "ACK")) {
strcpy(response, "TERM");
sendto(sockfd, (const char*)response, strlen(response), MSG_CONFIRM, (const struct
sockaddr*)&next_client_addr, sizeof(next_client_addr));
printf("Exiting\n");
} else {
printf("Invalid message recieved\n");
}
exit(0);
} else {
while (1) {
memset(&prev_client_addr, 0, sizeof(prev_client_addr));
printf("Ready to Listen \n");
n = recvfrom(sockfd, (char*)buffer, MAXLINE, MSG_WAITALL, (struct
sockaddr*)&prev_client_addr, &len);
buffer[n] = '\0';
if (!strcmp(buffer, "ACK")) {
critical_section(MY_PORT);
printf("Printing %s to port %d. \n", buffer, NEXT_CLIENT_PORT);
sendto(sockfd, (const char*)buffer, strlen(buffer), MSG_CONFIRM, (const struct
sockaddr*)&next_client_addr, sizeof(next_client_addr));
} else if (!strcmp(buffer, "TERM")) {
printf("Printing %s to port %d. \n", buffer, NEXT_CLIENT_PORT);
sendto(sockfd, (const char*)buffer, strlen(buffer), MSG_CONFIRM, (const struct
sockaddr*)&next_client_addr, sizeof(next_client_addr));
printf("Exiting\n");
exit(0);
} else {
printf("Invalid message recieved\n");
}
}
}
}

PROGRAM OUTPUT:
Findings and Learnings:
1. We successfully implemented Token-Ring Mutual Exclusion.
2. This avoids Starvation
3. Lost Key is a major issue

Вам также может понравиться