How to safely end threads and get back to main?

119 Views Asked by At

I'm trying to write multithread program to calculate usage of processor. The problem is that i don't know how to safely end threads. I have to end them by signal SIGTERM and I tried while(flag), phread_exit(), exit(), return(void*)0 but non of them work. I need to end infinite loop and return to main function. I've got two results: Exiting the whole program or program stopped and do nothing. How can I solve it?

#include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include <signal.h>
    #include <ctype.h>
    #include <unistd.h>
    #include <sys/sysinfo.h>
    #include <ctype.h>
    #include <malloc.h>
    #include <time.h>
    #include <semaphore.h>
    #include "cpudata.h"
    #include"cpu_result.h"
    #include "reader.h"
    #include "analyzer.h"
    #include "writer.h"
    #define NUM_THREADS 3 //Number of threads
    
    //Declaring variables as volatile
    volatile struct cpu_data *datax1;
    volatile struct cpu_data *datax2;
    volatile struct cpu_result *result;
    
    //Declaring semaphores
    sem_t sem1;
    sem_t sem2;
    sem_t sem3;
    volatile int flag=1;
    volatile int val[NUM_THREADS]={0,0,0};
    
    void handle_sigterm(int signum)
    {
       flag=0;
    }
    
    void *reader(void *ptr) //Thread to read
    { while(flag){
        sem_post(&sem3);
        sem_wait(&sem1);
        sleep(1);           //Make sure that semaphores changes value
        load_data(datax1);
        sleep(1);           //Making sure that values datax1 and datax2 are different
        load_data(datax2);  
    
        if(datax1==datax2)  //checking if values are different
            {   
            perror("Datas are the same \n");
            }
        }
        pthread_exit(val[0]);
    }
    
    void *analyzer(void *ptr)//Thread to calculate data
    {   while(flag){
        
            sem_post(&sem1);
            sem_wait(&sem2);
            sleep(1);//Make sure that semaphores changes value
            
            for(int i=0;i<NOPT+1;i++)
                {
                result[i]=calculate(datax1[i],datax2[i]);//calculating data
                }        
        }
        pthread_exit(val[1]);
    }
    void *writer(void *ptr)//thread to write data 
    {  while(flag){
        
    sem_post(&sem2);
    sem_wait(&sem3);
    sleep(1);//Make sure that semaphores changes value

    writeresult(result);
    printf("\n\n\n\n\n\n");
    }
    pthread_exit(val[2]);
}



int main(int argc, char **argv)
{

    struct sigaction action;
    memset(&action,0,sizeof(struct sigaction));
    action.sa_handler=handle_sigterm;
    sigaction(SIGTERM,&action,NULL);

    //Allocating memory for data
    datax1=(struct cpu_data *)malloc((NOPT+1)*sizeof(struct cpu_data));
    datax2=(struct cpu_data *)malloc((NOPT+1)*sizeof(struct cpu_data));
    result=(struct cpu_result *)malloc((NOPT+1)*sizeof(struct cpu_result));

    pthread_t thread[NUM_THREADS];//declaring threads
    //Initializing semaphores
    sem_init(&sem1,0,1);
    sem_init(&sem2,0,1);
    sem_init(&sem3,0,1);

    //creating threads
    pthread_create(&thread[0],NULL, &reader, NULL);
    pthread_create(&thread[1],NULL, &analyzer, NULL);
    pthread_create(&thread[2],NULL, &writer, NULL);

    //make sure threads are working
    for(int i=0;i<NUM_THREADS;i++){
        pthread_join(thread[0],NULL);
        pthread_join(thread[1],NULL);
        pthread_join(thread[2],NULL);
    }
    //stopping threads
    for(int i=0;i<NUM_THREADS;i++){
        pthread_cancel(thread[0]);
        pthread_cancel(thread[1]);
        pthread_cancel(thread[2]);
    }
    
    //freeing memory
    sem_destroy(&sem1);
    sem_destroy(&sem2);
    sem_destroy(&sem3);
    free(datax1);
    free(datax2);
    free(result);
    printf("SAFETY CLOSING");
    return 0;
}
0

There are 0 best solutions below