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;
}