In: Computer Science
IN C LANGUAGE:
Write a multi-threaded Linux program that synchronizes it's threads to write to a file without the file becoming corrupted.
To do this, your program will create three threads which write strings to the same file. Each thread will randomly write a selection of strings to the file at random intervals. When finished, the file will contain all the strings written correctly to the file. You may use mutexes, semaphores, or a monitor your write on your own.
Each string in the file should be on it's own line. Each thread picks one of the strings at random and writes it to the file every 1 - 3 seconds, for a total of 20 lines.
Use the sleep() system call to spread out the time in between writes.
To write to the file, use the open(), write(), and close() system calls.
So the file will start something like this:
eleven
thirty five
fifteen
twenty two
.
.
.
and continue for 60 total lines.
Keep in mind, the strings are randomly chosen and in random order.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <limits.h>
#include <string.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
FILE *fptr;
int GetRandoms(int lower, int upper)
{
int num = (rand() % (upper - lower + 1)) + lower; ;
return num;
}
struct Node {
char data[100];
struct Node* next;
};
struct Node* CreateNode(char* data, struct Node* next)
{
struct Node* n = (struct Node*)malloc(sizeof(struct Node));
strcpy(n->data, data);
n->next = next;
return n;
}
void printList(struct Node* n)
{
while (n != NULL) {
printf("\n %s ", n->data);
n = n->next;
}
}
void WriteFile(char* data)
{
pthread_mutex_lock(&mutex);
fputs(data, fptr);
pthread_mutex_unlock(&mutex);
}
void *myThreadFun1(void *vargp)
{
int *myid = (int *)vargp;
struct Node* list = CreateNode("eleven\n",NULL);
list->next = CreateNode("twelve\n",NULL);
struct Node* endNode = list->next;
endNode->next = CreateNode("thirteen\n",NULL);
endNode = endNode->next;
endNode->next = CreateNode("fourteen\n",NULL);
endNode = endNode->next;
endNode->next = CreateNode("fifteen\n",NULL);
int nodeCount = 5;
int nodeToWrite = 0;
struct Node* writeNode;
for(int i = 0 ; i < 20; i++)
{
sleep(GetRandoms(1,3));
nodeToWrite = GetRandoms(1,nodeCount);
printf("\nThread Id : %d\tGoing to write index %d ",*myid,nodeToWrite);
if(nodeToWrite == 1)
{
writeNode = list;
}
else if (nodeToWrite == nodeCount)
{
writeNode = endNode->next;
}
else
{
struct Node* temp = list;
for(int j = 2; j < nodeToWrite; j++)
{
temp = temp->next;
}
writeNode = temp->next;
}
printf("\nThread Id : %d\tWriting %s ",*myid,writeNode->data);
WriteFile(writeNode->data);
}
return 0;
}
void *myThreadFun2(void *vargp)
{
int *myid = (int *)vargp;
struct Node* list = CreateNode("twenty one\n",NULL);
list->next = CreateNode("twenty two\n",NULL);
struct Node* endNode = list->next;
endNode->next = CreateNode("twenty three\n",NULL);
endNode = endNode->next;
endNode->next = CreateNode("twenty four\n",NULL);
endNode = endNode->next;
endNode->next = CreateNode("twenty five\n",NULL);
//printList(list);
int nodeCount = 5;
int nodeToWrite = 0;
struct Node* writeNode;
for(int i = 0 ; i < 20; i++)
{
sleep(GetRandoms(1,3));
nodeToWrite = GetRandoms(1,nodeCount);
printf("\nThread Id : %d\tGoing to write index %d ",*myid,nodeToWrite);
if(nodeToWrite == 1)
{
writeNode = list;
}
else if (nodeToWrite == nodeCount)
{
writeNode = endNode->next;
}
else
{
struct Node* temp = list;
for(int j = 2; j < nodeToWrite; j++)
{
temp = temp->next;
}
writeNode = temp->next;
}
//printList(list);
printf("\nThread Id : %d\tWriting %s ",*myid,writeNode->data);
WriteFile(writeNode->data);
}
return 0;
}
void *myThreadFun3(void *vargp)
{
int *myid = (int *)vargp;
struct Node* list = CreateNode("thirty one\n",NULL);
list->next = CreateNode("thirty two\n",NULL);
struct Node* endNode = list->next;
endNode->next = CreateNode("thirty three\n",NULL);
endNode = endNode->next;
endNode->next = CreateNode("thirty four\n",NULL);
endNode = endNode->next;
endNode->next = CreateNode("thirty five\n",NULL);
//printList(list);
int nodeCount = 5;
int nodeToWrite = 0;
struct Node* writeNode;
for(int i = 0 ; i < 20; i++)
{
sleep(GetRandoms(1,3));
nodeToWrite = GetRandoms(1,nodeCount);
printf("\nThread Id : %d\tGoing to write index %d ",*myid,nodeToWrite);
if(nodeToWrite == 1)
{
writeNode = list;
}
else if (nodeToWrite == nodeCount)
{
writeNode = endNode->next;
}
else
{
struct Node* temp = list;
for(int j = 2; j < nodeToWrite; j++)
{
temp = temp->next;
}
writeNode = temp->next;
}
//printList(list);
printf("\nThread Id : %d\tWriting %s ",*myid,writeNode->data);
WriteFile(writeNode->data);
}
return 0;
}
int main()
{
srand(time(0));
fptr = fopen("output.txt","w+");
if(fptr == NULL)
{
printf("\nError!");
exit(1);
}
int i;
pthread_t tid[3];
pthread_create(&tid[0], NULL, myThreadFun1, (void *)&tid[0]);
pthread_create(&tid[1], NULL, myThreadFun2, (void *)&tid[1]);
pthread_create(&tid[2], NULL, myThreadFun3, (void *)&tid[2]);
for (i = 0; i < 3; i++)
pthread_join(tid[i], NULL);
fclose(fptr);
printf("Exiting...");
return 0;
}
I hope this would be helpfull for you. if you like the answer give thumb up. If you have any query feel free to ask in comment section.