How to safely end threads and get back to main? - c

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

Related

I want to create C program that executes two threads at 10ms and 20ms periodically?

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *t1(){
long tid=9;
printf("thread ID %ld",tid);
}
void *t2(){
long tid=10;
printf("thread ID %ld",tid);
}
int main()
{
pthread_t thread1,thread2;
int rc;
int i=0;
rc =pthread_create(&thread1,NULL,t1,NULL);
if(rc)
{
printf("ERROR");
exit();
}
pthread_create(&thread2,NULL,t2,NULL);
return 0;
}
This is where I am at, I have created the threads and executed it but I don't know how to call those functions based on a timer.

POSIX Semaphores in C for using in 2 seperated programs (consumer/producer)

I'm trying to implement the producer/consumer problem in C. I know how to handle it with "fork", but in this case I shall implement two programs. One for producer and one for consumer.
For producer: a semaphore has to be initialized and in a loop (to 100), the semaphore shall increment its value and print it. This already works fine.
For consumer: the semaphore initialized in producer, shall be opened and in a loop (to 10) its value shall be decremented and printed.
When I run the process for consumer: a memory-access error is printed.
I have absolutely no idea, what I'm doing wrong. Thanks for any help!
consumer:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
int value;
sem_t *mySem = sem_open("sem", O_CREAT|O_EXCL , S_IRUSR|S_IWUSR , 0);
for(int i=0; i < 10; i++) {
sem_wait(mySem);
sem_getvalue(mySem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_close(mySem);
sem_unlink("sem");
return 0;
}
producer:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
sem_t sem;
int main() {
sem_init(&sem, 0, 0);
int value;
for(int i=0; i < 100; i++) {
sleep(1);
sem_post(&sem);
sem_getvalue(&sem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_destroy(&sem);
return 0;
}
Hmm, what do you expect sem_init(&sem, 0, 0); to do? What relationship does that sem have with the consumer?
For two unrelated processes to communicate over anyn IPC, they have to agree on a resource by name. That's true if they share a file. It's also true if they share a semaphore. That's what named semaphores are for.
I modified your programs to use one named semaphore. The producer creates it and owns it exclusively; the consumer errors out if it's not there.
Consumer:
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/types.h>
static const char name[] = "sem";
int main() {
int value;
sem_t *sem = sem_open(name, 0, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
for(int i=0; i < 10; i++) {
sem_wait(sem);
sem_getvalue(sem, &value);
printf("The value of the semaphore is %d\n", value);
}
if( -1 == sem_close(sem) ) {
err(EXIT_FAILURE, "sem_close");
}
if( -1 == sem_unlink(name) ) {
err(EXIT_FAILURE, "sem_unlink");
}
return 0;
}
Producer:
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static const char name[] = "sem";
int main() {
sem_unlink(name); // ignore error if not extant
int value;
sem_t *sem = sem_open(name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
for(int i=0; i < 100; i++) {
sleep(1);
sem_post(sem);
sem_getvalue(sem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_destroy(sem);
return 0;
}
I think you'll find they work better now. I recommend you follow my lead, though, and check every return code, and exit on error whenever anything goes wrong. For trial code like this, that's the quickest way to get it running correctly.
Thanks for correction. This works perfectly for my purpose.
With sem_init I supposed to initialize the semaphore with 0 as Start-Value.
Seems like the error was using this instead of a pointer and sem_open in the producer-process.
This was my first experience with named semaphores, so it was not easy to see my error.
Thank you very much

How to code a scalable muti-process program using semaphores in C

I am trying to code a scalable mutli-process program using semaphores. I already done the multi-process part with semaphores but now I am trying to make it scalable.
The method I would like to implement is adding another semaphore per process that will tell the process how many times he has to run through his code. The problem is that I don't know how to initialize the other semaphores and I am not sure of how to code it altogether.
So my question : how to initialize the other semaphores and what semop should I use ?
I understand that without a code sample it might be hard to answer but I cannot publish the code, if you want more information about my problem feel free to ask.
Thank you for your time and your answers.
Code sample :
/*INITIALIZATION*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <errno.h>
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
} sem0, sem1, sem2;
int main(int argc, char** argv){
int key=ftok("/tmp",'L');
int id=semget(key,3,0600 | IPC_CREAT | IPC_EXCL);
sem0.val=1;
sem1.val=0;
sem2.val=0;
semctl(id,0,SETVAL,sem0);
semctl(id,1,SETVAL,sem1);
semctl(id,2,SETVAL,sem2);
return 0;
}
/*FIRST PROCESS*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <errno.h>
void first(int d){
struct timespec* ts;
ts=malloc(sizeof(struct timespec));
ts->tv_sec=0;
ts->tv_nsec=1000*d;
int i;
char name[6]={'S','T','A','C','K',' '};
for(i=0;i<6;i++){
putchar(name[i]);
fflush(stdout);
nanosleep(ts,NULL);
}
}
struct sembuf in = {0,-1,0};
struct sembuf out = {1,1,0};
int main(int argc,char** argv){
int key=ftok("/tmp",'L');
int id=semget(key,0,0);
while(1){
semop(id,&in,1);
first(strtol(argv[1],NULL,0));
semop(id,&out,1);
}
return 0;
}
/*SECOND PROCESS*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <errno.h>
void first(int d){
struct timespec* ts;
ts=malloc(sizeof(struct timespec));
ts->tv_sec=0;
ts->tv_nsec=1000*d;
int i;
char name[4]={'O','V','E','R'};
for(i=0;i<4;i++){
putchar(name[i]);
fflush(stdout);
nanosleep(ts,NULL);
}
}
struct sembuf in = {1,-1,0};
struct sembuf out = {2,1,0};
int main(int argc,char** argv){
int key=ftok("/tmp",'L');
int id=semget(key,0,0);
while(1){
semop(id,&in,1);
first(strtol(argv[1],NULL,0));
semop(id,&out,1);
}
return 0;
}
/*THIRD PROCESS*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <errno.h>
void first(int d){
struct timespec* ts;
ts=malloc(sizeof(struct timespec));
ts->tv_sec=0;
ts->tv_nsec=1000*d;
int i;
char name[5]={'F','L','O','W','S'};
for(i=0;i<5;i++){
putchar(name[i]);
fflush(stdout);
nanosleep(ts,NULL);
}
putchar('\n');
}
struct sembuf in = {2,-1,0};
struct sembuf out = {0,1,0};
int main(int argc,char** argv){
int key=ftok("/tmp",'L');
int id=semget(key,0,0);
while(1){
semop(id,&in,1);
first(strtol(argv[1],NULL,0));
semop(id,&out,1);
}
return 0;
}
Here we have three process and i am using semaphores. Now what if i want to write the first word(process 1) x times, the second y times and the third z times. What i want to do is adding another semaphore to each process, the value of these semaphores will be the number of times the process must run through it's code. Can someone help me with that, i don't know how to semop on the count semaphores.

sem_wait seems to block after random number of iterations

I am trying to make my aperiodic task wait for a specific key press event.My
aperiodic function waits first time for the event to occur but post that it runs 3 iterations without waiting and then waits again. I am unable to discern mistake in the code. I have initialized the array of event semaphores with value 0 for each
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
sem_t mutex[10],event[10];
sem_t mtx,mtx1,mtx2,mtx3; //These 4 mutexes and the array mutex[10] are defined for periodic task
typedef struct task
{
int taskid;
int priority;
int iter;
}task;
void *wait_for_event()
{
int fd;
fd = open("/dev/input/by-path/platform-i8042-serio-0-event-kbd", O_RDONLY);
struct input_event ev;
while (1)
{
read(fd, &ev, sizeof(struct input_event));
if(ev.type == 1) /* signal any waiting thread for keypress event */
sem_post(&event[(ev.code -1)%10]);
}
}
void *aperiodic(void *t)
{
pthread_t tid;
sem_wait(&mtx);
while(1){
sem_wait(&mtx1);
int i,j;
struct task *temp=(struct task *)t;
printf(" The running task is : %d",temp->taskid);
/*do some busy computation */
for(i=0;i<temp->iter;i++)
{
j=i+j;
}
printf("\nTOTAL iterations %d\n", j);
printf("\n ENTERED APERIODIC TASK..Enter the input event id\n");
/*wait for event with the task id temp->taskid to occur. This sem_wait waits for keypress event. But it is not waiting in every iteration of while loop. It is waiting once in 3 iterations. */
sem_wait(&event[temp->taskid]);
sem_post(&mtx1);
}
in main method i have initialized
for(i=1;i<=10;i++)
{ /*the initial value of all mutexes in event array is 0 */
sem_init(&event[i],0,0);
}

Sem_wait() not blocking after first true condition

I am learning to use semaphores and below is a small scenario which I've tried to implement. Its behaving weird in a way. After sem_wait() gets unblocked first time, its not getting blocked again and keeps on looping, not getting why. Is this the right way or right scenario to use semaphore?
EDIT: I just realized that if I uncomment the sleep after sem_post, it works fine. .Reason being it was repeatedly doing sem_post() before thread could do coin=0 I believe. But is it right to use sleep this way with semaphores. I believe this would be considered a bad practice?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#define MAX_MSG_LEN 256
sem_t sem1;
sem_t sem2;
int coin=0;
void *thrdFun1(void *arg);
void *thrdFun2(void *arg);
void toggleCase(char *buf, int cnt);
int main()
{
pthread_t thrd1;
char argmsg1[] = "Thread1: Waiting to deliver\n";
int thNum;
int res;
res = sem_init(&sem1, 0,0);
// res = sem_init(&sem2, 0,0);
res = pthread_create(&thrd1, NULL, thrdFun1, argmsg1);
while(1)
{
if (coin==0)
{
printf("no coin: please enter coin\n");
scanf("%d",&coin);
}
else
{
sem_post(&sem1);
// sleep(1);
}
}
return 0;
}
void *thrdFun1(void *arg)
{
while(1)
{
printf("I'm %s\n",(char *)arg);
sem_wait(&sem1);
printf("Delivered...\n");
coin=0;
sleep(1);
}
}
Semaphores are used to control Critical-Section Access. In this case, critical section would be the output shell. The thread may or may not start promptly when the pthread_create() is called. Also, sem_wait() will decrease the value of sem1 with each call. Thus, when you include sleep(1) in the thrdFun1 function, there may be undefined behaviour :)
You need to remove sleep(1); from function thrdFun1. After this there will not be any need of sleep(1) in main.
You realized it right, it is repeatedly doing sem_post() before thread could do coin=0 when removing all sleeps.
To solve this you could use second semaphore (you already tried it seems) like below,
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#define MAX_MSG_LEN 256
sem_t sem1;
sem_t sem2;
int coin=0;
void *thrdFun1(void *arg);
void *thrdFun2(void *arg);
void toggleCase(char *buf, int cnt);
int main()
{
pthread_t thrd1;
char argmsg1[] = "Thread1: Waiting to deliver\n";
int thNum;
int res;
res = sem_init(&sem1, 0,0);
res = sem_init(&sem2, 0,0);
res = pthread_create(&thrd1, NULL, thrdFun1, argmsg1);
while(1)
{
if (coin==0)
{
printf("no coin: please enter coin\n");
scanf("%d",&coin);
}
else
{
sem_post(&sem1); // Coin is spun
sem_wait(&sem2); // Wait till it is caught
}
}
return 0;
}
void *thrdFun1(void *arg)
{
while(1)
{
printf("I'm %s\n",(char *)arg);
sem_wait(&sem1); // Wait to spin the coin
coin=0;
sem_post(&sem2); // inform as caught
printf("Delivered...\n");
}
}
there is a chance that "Thread1: Waiting to deliver" this string can get printed many times.
What you are trying to achieve is looks like producer-consumer problem.
You required two semaphore to achive this.
main function:
while(1)
{
if (coin==0)
{
printf("no coin: please enter coin\n");
scanf("%d",&coin);
}
else
{
sem_post(&sem1);
sem_wait(&sem2)
}
}
in thread function
while(1)
{
printf("I'm %s\n",(char *)arg);
sem_wait(&sem1);
printf("Delivered...\n");
coin=0;
sem_post(&sem2)
}

Resources