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).
Related
So this is for my project where I want to print current date and time and run timer.
But when I run the program it only prints the date and time . If I don't run it for infinite times then it only prints the time When I ran that program. And i need to run two infinite loops in same program.
One for current date and time and another for timer.
sorry for posting this rough code because my code is incomplete.
I just want to know how to run two infinite loops.
#include <stdio.h>
#include <time.h>
int main()
{
char cur_time[128];
for(;;)
{
time_t t;
struct tm* ptm;
t = time(NULL);
ptm = localtime(&t);
strftime(cur_time, 128, "%d-%b-%Y %H:%M:%S", ptm);
printf("\rCurrent date and time: %s", cur_time);
}
for(;;)
{
printf("I Can't print This Line !!");
}
return 0;
}
A single threaded program can only be executing one instruction at a time. In your program, the second while loop will never be reached.
You have a few options: master event loop, multithreading, or separate processes.
A master event loop is the easiest method. Simply have a single infinite loop, in which all your logic is placed.
Note that everything in the loop happens in order, which means you'll want to avoid blocking the execution (waiting for user input, long computations, etc.) if you want the appearance of concurrency.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
void display_time(void) {
char cur_time[128];
time_t t = time(NULL);
struct tm *ptm = localtime(&t);
strftime(cur_time, 128, "%d-%b-%Y %H:%M:%S", ptm);
printf("Current date and time: %s\n", cur_time);
}
int main(void) {
while (1) {
display_time();
puts("I can print this line.");
sleep(1);
}
}
Using threads is another option. Multithreading shares the environment of the process between different threads of execution, so care must be taken when sharing resources.
Here's an example using POSIX threads (-lpthread).
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
void display_time(void) {
char cur_time[128];
time_t t = time(NULL);
struct tm *ptm = localtime(&t);
strftime(cur_time, 128, "%d-%b-%Y %H:%M:%S", ptm);
printf("Current date and time: %s\n", cur_time);
}
void *time_thread(void *arg) {
while (1) {
display_time();
sleep(1);
}
}
int main(void) {
pthread_t thr;
if (pthread_create(&thr, NULL, time_thread, NULL)) {
fprintf(stderr, "Failed to create thread.\n");
return EXIT_FAILURE;
}
while (1) {
puts("I can print this line.");
sleep(1);
}
}
Using different processes is yet another option.
Here we duplicate our process' environment into a new process as soon as fork returns successfully (returning 0 in the child process, and the child's PID in the parent process), and execution resumes independently in both processes.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
void display_time(void) {
char cur_time[128];
time_t t = time(NULL);
struct tm *ptm = localtime(&t);
strftime(cur_time, 128, "%d-%b-%Y %H:%M:%S", ptm);
printf("Current date and time: %s\n", cur_time);
}
void child_proc(void) {
while (1) {
display_time();
sleep(1);
}
}
int main(void) {
pid_t pid = fork();
if (pid == -1) {
fprintf(stderr, "Failed to create child process.\n");
return EXIT_FAILURE;
}
if (pid == 0)
child_proc();
else while (1) {
puts("I can print this line.");
sleep(1);
}
}
If you don't want to complicate things with threads, then just switch between the functions in a single loop:
void do_thing_1() { printf("..."); }
void do_thing_2() { printf("..."); }
void loop() {
while (1) {
do_thing_1();
do_thing_2();
}
}
You'll probably want to control the timing a bit better than that, but it will work. I do this often in embedded systems where the individual functions are state machines handling some piece of hardware.
Here's my simple scheme. It maybe near to what you want.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <inttypes.h>
int main(void){
int loop1_counter = 0;
int loop2_counter = 0;
while(1){
printf("start of main loop\n");
for(;;){
printf("loop1 %d\n",loop1_counter);
loop1_counter++;
if(loop1_counter >= 5){
loop1_counter = 0;
break;
}
}
printf("between loop1 and loop2\n");
for(;;){
printf("loop2 %d\n",loop2_counter);
loop2_counter++;
if(loop2_counter >= 5){
loop2_counter = 0;
break;
}
}
printf("end of main loop\n");
}
return 0;
}
I would like to measure the CPU and User time passed between starting a process and sending SIGINT signal using C times function.
However, on print I just get 0. Can't see the problem..
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/times.h>
#include <signal.h>
struct tms time_start;
struct tms time_end;
clock_t start;
clock_t end;
void handle() {
times(&time_end);
end = time_end.tms_stime;
}
int main(int argc, char *argv[]) {
signal(SIGINT, handle);
times(&time_start);
start = time_start.tms_utime;
pause();
printf("end: %ld, start: %ld\n", (long) end, (long) start);
return 0;
}
This is the output I get:
k#sc:dir$ ./my_time
^Cend: 0, start: 0
on print I just get 0. Can't see the problem..
The tms_stime is the CPU time spend in the kernel on behalf of the process. pause() is doing nothing, so it doesn't count for CPU time, signal and times are not computationally demanding functions - your program is doing nothing. Do some I/O operations, get that kernel to work to see some changes in times.
For example the following program reads 400000000 bytes from /dev/urandom:
#include <time.h>
#include <sys/times.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
struct tms time_end;
void handle() {
times(&time_end);
}
int main(int argc, char *argv[]) {
signal(SIGINT, handle);
// read from urandom so that kernel has to generate randomness
FILE *f = fopen("/dev/urandom", "r");
for (int i = 0; i < 20000000; ++i) {
char buf[20];
fread(buf, sizeof(buf), 1, f);
}
fclose(f);
pause();
printf("tms_stime = %ld\n", (long)time_end.tms_stime);
return 0;
}
Saved as 1.c file and executed on my system in shell outputs:
$ sh -c 'gcc 1.c ; ./a.out & child=$!; sleep 2; kill -INT $child ; wait'
tms_stime = 127
On linux there is also CLOCK_PROCESS_CPUTIME_ID you might be interested in.
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
}
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.
I am trying to have a signal handler stop a timer without exiting my program. How should I go about. I want StopTimer to handle the signal to stop the timer
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#define INTERVAL 2 // number of seconds to go off
int main(int argc, char* argv[]) {
TimerSet(INTERVAL);
while(1)
{
// do stuff
}
return 0;
}
void TimerSet(int interval)
{
printf("starting timer\n");
struct itimerval it_val;
// interval value
it_val.it_value.tv_sec = interval;
it_val.it_interval = it_val.it_value;
// on SIGALRM, close window
if (signal(SIGALRM, TimerStop) == SIG_ERR)
{
perror("Unable to catch SIGALRM");
exit(1);
}
// set interval timer, returns SIGALRM on expiration
if (setitimer(ITIMER_REAL, &it_val, NULL) == -1)
{
perror("error calling setitimer()");
exit(1);
}
}
void TimerStop(int signum)
{
printf("Timer ran out! Stopping timer\n");
exit(signum);
}
I tried to set the setitimer interval to 0, but I am not sure how to use the same timer within the TimerStop signal handler function
Just set it_interval to zero, and you'll get a one-shot timer. You don't need to do anything with it in your handler.
For instance, with this:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#define INTERVAL 2 // number of seconds to go off
void TimerStop(int signum) {
printf("Timer ran out! Stopping timer\n");
}
void TimerSet(int interval) {
printf("starting timer\n");
struct itimerval it_val;
it_val.it_value.tv_sec = interval;
it_val.it_value.tv_usec = 0;
it_val.it_interval.tv_sec = 0;
it_val.it_interval.tv_usec = 0;
if (signal(SIGALRM, TimerStop) == SIG_ERR) {
perror("Unable to catch SIGALRM");
exit(1);
}
if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
perror("error calling setitimer()");
exit(1);
}
}
int main(int argc, char *argv[]) {
TimerSet(INTERVAL);
while (1) {
// do stuff
}
return 0;
}
the message "Timer ran out! Stopping timer" will appear only once, and your timer will stop without you doing anything.
Note that you need to fill in the tv_usec members of your struct itimerval, which your current code does not do. If you don't, it_interval is highly unlikely to be zero, and your timer will never stop.
printf(), along with the other standard IO functions, is not really safe to call from a signal handler, although in this particular case it won't cause you any problems, since the main code is just sitting in a loop and not doing anything.
Also, presume you're calling signal() on purpose - sigaction() is the recommended way for setting handlers. setitimer() is also obsolete, now, and timer_settime() is recommended.
According to manual:
Timers decrement from it_value to zero, generate a signal, and reset to
it_interval. A timer which is set to zero (it_value is zero or the timer
expires and it_interval is zero) stops.
Both tv_sec and tv_usec are significant in determining the duration of a
timer.
So timer can be set to run only once if interval is set to zero before setitimer() call (thanks to Duck's comment).