Creating a auto terminating main function - c

The following program implements two array of threads.There are two thread functions student and teacher(I have not shown them here). My sample program is given below. I want to make a time limit(say 10 sec) after which the main thread will automatically exit no matter if others threads have completed or not.I also want to the current time every moment after starting of the program. How will I do that?
Sample code fragment:
int main(void)
{
pthread_t thread1[25];
pthread_t thread2[6];
int i;
int id1[25]; //for students
int id2[6]; //for teachers
for(i=0;i<25;i++)
{
id1[i]=i;
id2[i]=i;
pthread_create(&thread1[i],NULL,student,(void*)&id1[i] );
if(i<6)
{
pthread_create(&thread2[i],NULL,teacher,(void*)&id2[i]);
}
}
for (i=0;i<25;i++)
{
pthread_join(thread1[i],NULL);
if(i<6)
{
pthread_join(thread2[i],NULL);
}
}
return 0;
}
What additional things will I have to add to the above code to terminate the main thread after a certain time? (say: 10 seconds)

You can use pthread_timedjoin_np() for this passing a timespec struct. You can set the struct to timeout after 10 seconds like this:
struct timespec tp;
tp.tv_sec = 10;
tp.tv_nsec = 0;
Then you change your calls to join pthread_timedjoin_np(myThread, &tp). Regarding how you can get the current time, the simplest method is to use gettimeofday function.
Another perhaps simpler approach is to use a alarm. You can have a function which will exit the application. So you would do something like this:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
void alarmhandler(int sig) {
printf("Ten seconds passed, quitting!\n");
exit(0);
}
int main() {
int i, j;
struct timeval end, start;
signal(SIGALRM, alarmhandler);
alarm(4);
gettimeofday(&start, NULL);
sleep(3); // simulate thread work
gettimeofday(&end, NULL);
long elapsed = (end.tv_sec-start.tv_sec)*1000000 + end.tv_usec-start.tv_usec;
printf("%f seconds elapsed!\n", (float)(elapsed)/1000000.0f);
for(;;); // block indefinitely
}

Related

How to join/detach/clean dynamic malloc threads that are created per function call?

I wrote a sample code of my problem. In the while loop, I am dynamically creating new threads per function call, which will be processed in the calculate function. This could potentially take several seconds to finish and I used sleep to simulate this.
How do I clean these threads? They have separate threads with their own stack of args, so would it be possible to clean them in the calculate function at the end per call? But then I would run into the problem of some threads still calculating when the condition of random == 2 is met and the program exits.
I'm thinking of a variable that would change state when the calculation has finished, but still have the same problem as described above. Any ideas?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
struct args_struct {
pthread_t pt;
int random;
};
void* calculate(void *arguments){
struct args_struct *args = arguments;
sleep(args->random);
printf("Number: %d. %s", args->random, "Calculations completed, thanks for waiting!");
}
int main(){
while(1){
struct args_struct *args = malloc(sizeof (struct args_struct));
time_t t;
srand((unsigned) time(&t));
args->random = rand() % 5;
if(pthread_create( &args->pt, NULL, calculate, (void *)&args) != 0)
printf("Error in creating thread!");
if (args->random == 2 ){ //random condition in exiting loop
printf("Number is %d. Exiting program and joining remainder threads still running...", args->random);
//pthread_join? free(args)? pthread_exit? pthread_detach?
//pthread_join(args->pt, NULL);
//free(args);
return 0;
};
}
}
Argument args of pthread_create() is wrong.
Try change (void *)&args -> (void *)args.
Default stdout stream buffering is line buffering(_IOLBF).
Try insert '\n' character to printf() function.
Create seed(srand function) only once.
Finally, try the following.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>
struct args_struct {
pthread_t pt;
int random;
};
void* calculate(void *arguments){
struct args_struct *args = arguments;
sleep(args->random);
printf("Number: %d. %s\n", args->random, "Calculations completed, thanks for waiting!");
if (args->random != 2) free(args);
}
int main(){
time_t t;
srand((unsigned) time(&t));
while(1){
struct args_struct *args = malloc(sizeof (struct args_struct));
args->random = rand() % 5;
if(pthread_create( &args->pt, NULL, calculate, (void *)args) != 0)
printf("Error in creating thread!\n");
if (args->random == 2 ){ //random condition in exiting loop
printf("Number is %d. Exiting program and joining remainder threads still running...\n", args->random);
pthread_join(args->pt, NULL);
free(args);
return 0;
};
}
}

creating time specific threads

I have written a sample program to implement array of threads.There are two thread functions. Is there any way to define a fixed value of time (in seconds) after which all the threads will automatically stop?
Sample program:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
void * threadFunc1(void * arg)
{
int id = *((int *) arg);
printf("Inside threadfunc2 for thread %d\n",id)
while(1);
}
void * threadFunc2(void * arg)
{
int i= *((int *)arg);
printf("Inside threadfunc2 for thread %d\n",i)
while(1);
}
int main(void)
{
pthread_t thread[10];
for(int i=0;i<10;i++)
{
pthread_create(&thread[i],NULL,threadFunc1,(void*)&i );
pthread_create(&thread[i],NULL,threadFunc,(void*)&i );
}
for (i=0;i<total;i++)
{
pthread_join(thread[i],NULL);
}
return 0;
}
Instead of waiting for the threads with pthread_join you could put your main thread to sleep, e.g with nanosleep. If you then quit your main without joining, your whole process will be killed.
No, there is not. Threads do not 'automatically stop'

Limit execution time of function in c

I would like to limit the execution of a function in pure C, without stopping the whole program.
I believe the closest thing on stackoverflow.com to this was on the last comment of this thread: How to limit the execution time of a function in C/POSIX?
There was some talk of using setjmp and longjm placed after the function to limit in time, but the thread died.
Is there anyone that knows if this is indeed possible?
Cheers
I can see two options, first one check the time every few lines of code and return if it's too much, but I don't think it's a good idea.
Second, you could use threads. Run two functions at the same time, one timing the other, if the time is too big then it kills the first one. Now I'm pretty sure that windows and Linux have different libraries to create threads so you could try and use a library that works across all platforms like this one maybe http://openmp.org/wp/.
I'm not too familiar with that library and threads in general but I hope it helps
Though it could be of service to post my solution. It is a combination of this post http://cboard.cprogramming.com/c-programming/148363-limit-execution-time-function.html, and the IPC TPL example found here: https://github.com/troydhanson/tpl/blob/master/doc/examples.txt.
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <stdbool.h>
#include <string.h>
#include "tpl.h"
//This example contains two different parts:
//1) The alarm is a execution timer for the function doWork
//2) There is a need, that if the execution exits correctly, that the chid value of i, that we are modifying be passes
typedef struct TEST_STRUCT
{
int i;
double sum;
} testStruct;
int doWork(testStruct * ts)
{
int y;
for(y=0; y<3; y++)
{
sleep(1);
printf("Working: %d\n", ts->i);
ts->i++;
ts->sum += (double)ts->i;
}
return 0;
}
int main()
{
testStruct * ts = (testStruct *)(calloc(1, sizeof(testStruct)));
ts->i = 7;
ts->sum = 4.0;
tpl_node *tn;
int fd[2];
pipe(fd);
int y;
for(y=0; y<10; y++)
{
pid_t childPID = fork();
if (childPID==0)
{
unsigned secsLeft;
alarm(10);
doWork(ts);
printf("\t->%d\n", ts->i);
printf("\t->%p\n", (void*) &ts->i);
tn = tpl_map("S(if)", ts);
tpl_pack( tn, 0 );
tpl_dump( tn, TPL_FD, fd[1]);
tpl_free( tn );
secsLeft = alarm(0);
exit(0);
}
else
{
//IMPORTANT TO PUT IT HERE: In case the buffer is too big, TPL_DUMP will wait until it can send another and hang
tn = tpl_map( "S(if)", ts );
tpl_load( tn, TPL_FD, fd[0]);
int status;
wait(&status);
if(WIFSIGNALED(status))
{
// child was interrupted
if (WTERMSIG(status) == SIGALRM)
{
printf("Interrupted\n");
// child interrupted by alarm signal
}
else
{
printf("Should not happend\n");
// child interrupted by another signal
}
}
else
{
tpl_unpack(tn,0);
tpl_free( tn );
printf("\t->%d\n", ts->i);
printf("\t->%p\n", (void*) &ts->i);
printf("Success\n");
}
}
}
return 0;
}
Basically, we fork the program, where the child performs a task and the parent waits for the child to finish. The child contains an alarm, that if true signals the parent that it existed in that manner. If it completes (as this example shows), the child sends the object function to the parent as a TPL buffer.

Multithreaded semaphore program

I've spent quite a few hours on trying to figure this one out and I'm completly stuck. The program is supposed to start 6 threads. Where some threads start where others end. Right now, I'm trying to get one single thread (thread 0) to execute. The caps lock commenting shows where I have added code and done my mistakes. My main struggle here is dealing with the pointers. Could anyone give me any pointers (ha..ha.. :c )?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define SHARED 1
sem_t sem[6];
struct threadargs
{
int id; /* thread number */
int sec; /* how many sec to sleep */
int signal[6]; /* which threads to signal when done */
};
void *tfunc(void *arg)
{
int i;
struct threadargs *targs=arg;
sem_wait(sem); //WAIT FOR OWN SEMAPHORE
printf("Thread %d is running\n", targs->id);
sleep(targs->sec);
printf("Thread %d is completed and may wake others..\n", targs->id);
for(i=0; i<6; i++) //ITERATE OVER signal_ARRAY &
{ //WAKE THREAD NUMBER i IF
if(targs->signal[i] == 1) //signal[i] IS 1
pthread_cond_signal(&sem[i]);
}
}
int main(void)
{
int i, j;
struct threadargs *targs[6];
pthread_t tid[6];
for(i=0; i<6; i++)
{
targs[i] = (struct threadargs*) malloc(sizeof(struct threadargs));
for(j=0; j<6; j++)
{ targs[i]->signal[j]=0; }
}
targs[0]->id=1;
targs[0]->sec=1;
targs[0]->signal[1]=1;
targs[0]->signal[4]=1;
sem[0] = 0; //INITIALIZE THREAD'S SEMAPHORE TO 0 or 1
pthread_create(targs[0], NULL, tfunc, NULL) // START THREAD
for(i=0; i<6; i++)
pthread_join(tid[i], NULL);
return 0;
}
Alright. First things first, I do recommend taking a second look at your coding style. It is of course highly subjective and I won't say yours is bad, but it took me a while to figure it out (if you really want to know, I recommend the Linux coding style for C/C++ code).
Lets get on with your problem. As far as I can see, the main issue seems that you're basically comparing pointers to apples with pointers to banana's (in other words, you're using the wrong pointer type in the wrong place).
To make sure that calls to functions and the like are correct, make sure to look up the API documentation for functions that are new to you (examples: pthread_create, sem_init, sem_wait, sem_post, pthread_cond_signal).
As you can see, pthread_cond_signal doesn't take a sem_t* as argument, and therefore you can't pass one to it and expect it to work. Below you'll find an example program showing how semaphores are used.
First, a new thread is created which will be put in waiting state instantly. As soon as the main tread finished counting from 0 to 150, it will post ('unlock') the semaphore and allowing the second thread to finish its execution.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
static sem_t sem_thread_one;
static pthread_t thread_one_data;
static int x;
static void *tfunc(void *arg)
{
sem_wait(&sem_thread_one);
printf("Thread 1 is running. The value of x is %i\n", x);
return NULL;
}
int main(int argc, char **argv)
{
sem_init(&sem_thread_one, 0 /* don't share between processes */, 0);
if(pthread_create(&thread_one_data, NULL, &tfunc, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
while(x < 150) {
x++;
}
sem_post(&sem_thread_one);
if(pthread_join(thread_one_data, NULL)) {
fprintf(stderr, "Could not join threads, exiting!\n");
return -EXIT_FAILURE;
}
sem_destroy(&sem_thread_one);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
Save in a file sem.c and compile & link using:
gcc -Wall -Os -pthread -o sem_test sem.c
Now a second example, but now using pthread_cond_t. The functionality of the program is somewhat similar, it waits for a counter to reach a certain number.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
static pthread_t thread_one_data, thread_two_data;
static volatile int x, y, idx = 10;
static int count = 1;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
static void *cond_test_wait(void *arg)
{
pthread_mutex_lock(&mutex);
while(count < 10) {
printf("Waiting for `count < 10' to become true\n");
pthread_cond_wait(&condition, &mutex);
}
pthread_mutex_unlock(&mutex);
printf("Test wait thread finished. Value of count: %i\n", count);
return NULL;
}
static void *cond_test_signal(void *arg)
{
while(count < 10) {
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
/* do more intelligent things here */
count++;
pthread_mutex_unlock(&mutex);
}
printf("Test signal thread finished\n");
return NULL;
}
int main(int argc, char **argv)
{
if(pthread_create(&thread_one_data, NULL, &cond_test_wait, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
if(pthread_create(&thread_two_data, NULL, &cond_test_signal, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
pthread_join(thread_one_data, NULL);
pthread_join(thread_two_data, NULL);
pthread_cond_destroy(&condition);
pthread_mutex_destroy(&mutex);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
Save in a file cond.c and compile & link using:
gcc -o cond -pthread -Os -Wall cond.c
Do note how neat condition work in this example. You can use them to wait until any expression (= condition) becomes true. After the condition becomes true normal execution continue's.
If you need any more help, don't hesitate to ask in the comments. Good luck combining the above examples to fix up your program.

Runtime limit timer in C

I want to set a runtime limit (in hours) to my algorithm in C, so that when it reaches the limit, the algorithm stops (for example, at 12 hours). Does anyone have any suggestions how to do this?
You can use time() to obtain the time at start, and time at each iteration in your algorithm. You can use difftime() to calculate the difference and terminate the algorithm when it exceeds a certain value.
Assuming, your algorithm is iterative, here is a sample code that terminates the loop after 5 seconds.
#include <stdio.h>
#include <time.h>
int main(int argc, char **argv)
{
time_t start_time;
time_t now_time;
time(&start_time);
while (1) {
/* Your algorithm goes here */
/* Time check code */
time(&now_time);
if (difftime(now_time, start_time) >= 5) {
break;
}
}
return 0;
}
This is a very simple solution that works for many cases where you know that your time check code would be called often during the execution of the algorithm. If you are unable to find a good spot where you can place the time check code such that it is called often during the execution of the algorithm, an alternate approach would be to run your algorithm in a thread and kill it when the limit exceeds.
#include <stdio.h>
#include <time.h>
#include <pthread.h>
void *algo(void *arg)
{
while (1) {
printf("I AM THE ALGO!!\n");
}
return NULL;
}
int main(int argc, char **argv)
{
time_t start_time;
time_t now_time;
pthread_t algo_thread;
int ret = pthread_create(&algo_thread, NULL, algo, NULL);
time(&start_time);
/* Time check loop */
while (1) {
time(&now_time);
if (difftime(now_time, start_time) >= 5) {
break;
}
}
return 0;
}
Since this is Linux, you might find it handy to use alarm() (provided your algorithm doesn't need any calls that might interfere with, such as sleep()). Then you can register a handler for SIGALRM using sigaction(). When the alarm pops, you'll handle the signal however you handle timeouts. Here's a minimal example how you might use it:
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void timeout_handler (int signum) {
fprintf(stderr, "Timed out (signal:%d)!\n", signum);
exit(1);
}
int main (void) {
struct sigaction sa = { 0 };
sa.sa_handler = timeout_handler;
sigaction(SIGALRM, &sa, NULL);
alarm(5);
for (;;);
return 0;
}
This waits 5s time timeout and exit in the code above. If you want to do something other than exit, you could for example set a global value to indicate that the algorithm should exit (obviously be mindful if you're using threads).

Resources