Sample code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <time.h>
sem_t running;
sem_t even;
sem_t odd;
void logStart(char *tID); //function to log that a new thread isstarted
void logFinish(char *tID); //function to log that a thread hasfinished its time
void startClock(); //function to start program clock
long getCurrentTime(); //function to check current time sinceclock was started
time_t programClock; //the global timer/clock for theprogram
typedef struct thread //represents a single thread, you can addmore members if required
{
char tid[4]; //id of the thread as read fromfile
unsigned int startTime;
int state;
pthread_t handle;
int retVal;
} Thread;
//you can add more functions here if required
int threadsLeft(Thread *threads, int threadCount);
int threadToStart(Thread *threads, int threadCount);
void* threadRun(void *t); //the thread function, the codeexecuted by each thread
int readFile(char *fileName, Thread **threads); //function toread the file content and build array of threads
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Input file namemissing...exiting with error code -1\n");
return -1;
}
//you can add some suitable code anywhere inmain() if required
Thread *threads = NULL;
int threadCount = readFile(argv[1],&threads);
startClock();
while (threadsLeft(threads, threadCount) > 0)//put a suitable condition here to run your program
{
//you can add some suitable codeanywhere in this loop if required
int i = 0;
while ((i = threadToStart(threads,threadCount)) > -1) {
//you can add somesuitable code anywhere in this loop if required
threads.state =1;
threads.retVal =pthread_create(&(threads.handle), NULL,
threadRun, &threads);
}
}
return 0;
}
int readFile(char *fileName, Thread **threads) //do not modifythis method
{
FILE *in = fopen(fileName, "r");
if (!in) {
printf(
"ChildA: Error in opening input file...exiting with error code-1\n");
return -1;
}
struct stat st;
fstat(fileno(in), &st);
char *fileContent = (char*) malloc(((int)st.st_size + 1) * sizeof(char));
fileContent[0] = '\0';
while (!feof(in)) {
char line[100];
if (fgets(line, 100, in) != NULL){
strncat(fileContent,line, strlen(line));
}
}
fclose(in);
char *command = NULL;
int threadCount = 0;
char *fileCopy = (char*)malloc((strlen(fileContent) + 1) * sizeof(char));
strcpy(fileCopy, fileContent);
command = strtok(fileCopy, "\r\n");
while (command != NULL) {
threadCount++;
command = strtok(NULL, "\r\n");
}
*threads = (Thread*) malloc(sizeof(Thread) *threadCount);
char *lines[threadCount];
command = NULL;
int i = 0;
command = strtok(fileContent, "\r\n");
while (command != NULL) {
lines = malloc(sizeof(command) *sizeof(char));
strcpy(lines, command);
i++;
command = strtok(NULL, "\r\n");
}
for (int k = 0; k < threadCount; k++) {
char *token = NULL;
int j = 0;
token = strtok(lines[k], ";");
while (token != NULL) {
//if you have extended the Thread struct then here
//you can do initialization of those additional members
//or any other action on the Thread members
(*threads)[k].state =0;
if (j == 0)
strcpy((*threads)[k].tid, token);
if (j == 1)
(*threads)[k].startTime = atoi(token);
j++;
token = strtok(NULL,";");
}
}
return threadCount;
}
void logStart(char *tID) {
printf("[%ld] New Thread with ID %s isstarted.\n", getCurrentTime(), tID);
}
void logFinish(char *tID) {
printf("[%ld] Thread with ID %s is finished.\n",getCurrentTime(), tID);
}
int threadsLeft(Thread *threads, int threadCount) {
int remainingThreads = 0;
for (int k = 0; k < threadCount; k++) {
if (threads[k].state > -1)
remainingThreads++;
}
return remainingThreads;
}
int threadToStart(Thread *threads, int threadCount) {
for (int k = 0; k < threadCount; k++) {
if (threads[k].state == 0 &&threads[k].startTime == getCurrentTime())
return k;
}
return -1;
}
void* threadRun(void *t) //implement this function in a suitableway
{
logStart(((Thread*) t)->tid);
//your synchronization logic will appear here
//critical section starts here
printf("[%ld] Thread %s is in its criticalsection\n", getCurrentTime(),
((Thread*)t)->tid);
//critical section ends here
//your synchronization logic will appear here
logFinish(((Thread*) t)->tid);
((Thread*) t)->state = -1;
pthread_exit(0);
}
void startClock() {
programClock = time(NULL);
}
long getCurrentTime() //invoke this method whenever you wantcheck how much time units passed
//since you invoked startClock()
{
time_t now;
now = time(NULL);
return now - programClock;
}
Question 3 In this question, a process will create multiple threads at different times, as in Question 3 of assignment 2. These threads may have different start time but there is no lifetime. Each thread after its creation runs a small critical section and then terminates. All threads perform same action/code. Most of the code such as reading the input file, creating the threads etc. is provided. Your task is to implement following synchronization logic with the help of POSIX semaphores: Only one thread can be in its critical section at any time in this process. The first thread, in terms of creation time, enters first in its critical section. After those threads are permitted to perform their critical section based on their ID. O O O Threads are given IDs in the format txy where x and y are digits (0-9). Thread IDs are unique. Threads may have same or different start_time. Thread entries in the input file can be in any order. The "y" in thread IDs thus will either be an even digit or odd digit. O After the first thread, the next thread that will be permitted to perform its critical section must be the one in which "y" is different i.e. if "y" was even in first thread then in the next it must be odd or vice versa. For the rest of the process, you must follow the same scheme i.e. two threads with odd "y" or even "y" can not perform critical section simultaneously. Since synchronization may lead to deadlock or starvation, you must make sure that your solution is deadlock free i.e. your program must terminate successfully, and all the threads must perform their critical section. One extended form of starvation will be that towards the end, we have all odd or all even processes left, and they are all locked. Once the process reaches to that stage, you must let them perform their critical section to avoid starvation. However, you must make sure that there are no other threads coming in future which could help avoid this situation.
Description of Question 3: For this Question, you are provided a skeleton code in the file Sample_Code_Skeleton_Q2. c. Some functions are completely implemented, and some are partially implemented. Additionally, you can write your own functions if required. Complete the program as per following details so that we can have functionality as described in the Synopsis above. Write all the code in single C file: 2. The code provided reads the content of file for you and populate the threads information in a dynamic array of type struct thread. You may some more members to this data structure. If you want to initialize those members, then you can possibly do that during the file read. 3. The main () function already contains the code to create and invoke threads. However, there is no synchronization logic added to it. If required, you will add some suitable code in the while loops perform the tasks required. 4. The threadRun () function also contains the code that a thread must run. However, again the synchronization logic is missing. Add the suitable code before and after the critical section. 5. You will need to create and use POSIX semaphore(s) to implement the required logic. 6. The image below shows the expected output for the sample input file provided with this assignment:
[1] New Thread with ID t00 is started. [1] Thread t00 is in its critical section [1] Thread with ID t00 is finished. [2] New Thread with ID t03 is started. [2] Thread t03 is in its critical section [2] Thread with ID t03 is finished. [3] New Thread with ID t07 is started. [4] New Thread with ID t05 is started. [5] New Thread with ID t02 is started. [5] Thread t02 is in its critical section [5] Thread with ID t02 is finished. [5] Thread t07 is in its critical section [5] Thread with ID t07 is finished. [20] New Thread with ID t01 is started. [20] Thread t01 is in its critical section [20] Thread with ID t01 is finished. [20] Thread t05 is in its critical section [20] Thread with ID t05 is finished.
Sample code: #include #include #include #include #include #includ
-
- Site Admin
- Posts: 899603
- Joined: Mon Aug 02, 2021 8:13 am