-1

I need to run a while loop in C for exactly 10 seconds. I tried this:

clock_t start = clock();

while( ( clock() - start ) < ( 10 * CLOCKS_PER_SEC ) ) {

work..

}

but it is not working.

tr1umph
  • 11
  • 4
  • 2
    `CLOCKS_PER_SECOND` should be `CLOCKS_PER_SEC`. – Adrian Mole May 13 '20 at 17:57
  • @AdrianMole oh it is CLOCKS_PER_SEC instead of CLOCKS_PER_SECOND but I wrote it wrong to here. Sorry. Still CLOCKS_PER_SEC is not working. – tr1umph May 13 '20 at 17:59
  • 2
    Can you describe 'not working' in a bit more detail? I tried your code (inserting a simple `printf` statement in the loop body) and it works well. (`MSVC`, Windows 10). – Adrian Mole May 13 '20 at 18:00
  • 1
    `clock()` may return `-1` to indicate unavailability. Anyway, `clock()` measures processor time; time spent waiting for network (keyboard, disk, ...) activity is not processor time. If you can use POSIX, try [`clock_gettime()`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html) – pmg May 13 '20 at 18:07
  • @tr1umph I see you are new to stackoverflow. This site works on reputation points. When somebody provides you with useful information in the form of an answer you should typically either check the best answer as the accepted answer or upvote some answers that helped you. This way the people taking the time to help you out get some reputation points. It's really just command courtesy here. I've checked your history. You haven't accepted a single answer. Even though a few people posted answers that helped you. – Chimera May 13 '20 at 19:35

2 Answers2

0

Please specify what is not working. I'm gonna guess:

On Debian 10 the correct macro is CLOCKS_PER_SEC. But maybe Ubuntu added CLOCKS_PER_SECOND as an alias, in which case that is not the problem you have.

The way you implemented your timer, you may loop further than 10 seconds (if your "work" time is not a divisor of 10s). If that is your actual issue, you should check asynchronous tasks and signals. This way you can have one process (or thread) making your initial work in a infinite loop, and a second process notifying the first one (eg. with a signal) after 10 seconds elapsed. But that will require a much more complex code!

I hope I brought you some help, but if I did not try to be more precise in your question.

prg
  • 36
  • 2
0

Seems like what you may really want is an actual timer so that when a specified time interval passes a function is called. In that function you can handle disconnecting clients from the server.

See: https://programming.vip/docs/linux-c-language-timer.html

You should be able to modify this example to do as you need:

#include<stdio.h>
#include<signal.h>
#Include<sys/time.h>//itimerval structure definition

int handle_count=0;
void set_time(void)
{
   struct itimerval itv;
   itv.it_interval.tv_sec=10;//Load automatically and then respond every 10 seconds
   itv.it_interval.tv_usec=0;
   itv.it_value.tv_sec=5;//Time of First Timing
   itv.it_value.tv_usec=0;
   setitimer(ITIMER_REAL,&itv,NULL);
}

void alarm_handle(int sig)
{
   handle_count++;
   printf("have handle count is %d\n",handle_count);
}

void main(void)
{
   struct itimerval itv;
   signal(SIGALRM,alarm_handle);
   set_time();

   while(1){
   getitimer(ITIMER_REAL,&itv);
   printf("pass second is %d\n",(int)itv.it_value.tv_sec);
   sleep(1);
   }

   return;
}

Some man page links:

Another example from another StackOverflow answer:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>

static unsigned int pass_value_by_pointer = 42;

void Timer_has_expired(union sigval timer_data)
{
    printf("Timer expiration handler function; %d\n", *(int *) timer_data.sival_ptr);
}

int main(void)
{
    struct sigevent timer_signal_event;
    timer_t timer;

    struct itimerspec timer_period;

    printf("Create timer\n");
    timer_signal_event.sigev_notify = SIGEV_THREAD;
    timer_signal_event.sigev_notify_function = Timer_has_expired;       // This function will be called when timer expires
    // Note that the following is a union. Assign one or the other (preferably by pointer)
    //timer_signal_event.sigev_value.sival_int = 38;                        // This argument will be passed to the function
    timer_signal_event.sigev_value.sival_ptr = (void *) &pass_value_by_pointer;     // as will this (both in a structure)
    timer_signal_event.sigev_notify_attributes = NULL;
    timer_create(CLOCK_MONOTONIC, &timer_signal_event, &timer);

    printf("Start timer\n");
    timer_period.it_value.tv_sec = 1;                                   // 1 second timer
    timer_period.it_value.tv_nsec = 0;                                  // no nano-seconds
    timer_period.it_interval.tv_sec = 0;                                // non-repeating timer
    timer_period.it_interval.tv_nsec = 0;

    timer_settime(timer, 0, &timer_period, NULL);
    sleep(2);

    printf("----------------------------\n");
    printf("Start timer a second time\n");
    timer_settime(timer, 0, &timer_period, NULL);
    sleep(2);

    printf("----------------------------\n");
    printf("Start timer a third time\n");
    timer_settime(timer, 0, &timer_period, NULL);

    printf("Cancel timer\n");
    timer_delete(timer);
    sleep(2);
    printf("The timer expiration handler function should not have been called\n");

    return EXIT_SUCCESS;
}
Chimera
  • 5,884
  • 7
  • 49
  • 81