2010-10-25 2 views
1

Я хочу запустить бесконечный цикл на некоторое время. В принципе, я хочу, чтобы иметь что-то вроде этогоПробег бесконечный цикл в c

//do something 

while(1){ 
    //do some work 
} 

//do some other thing 

, но я хочу, чтобы время работы цикла быть фиксированным, пример, цикл может быть запущен в течение 5 секунд. У кого-нибудь есть идея?

+2

Нужна дополнительная информация, есть ли причина, по которой вы не можете просто спать? – user318904

+0

Может понадобиться для приложения реального времени. Я просто размышляю. –

+11

Название oxymoron :) –

ответ

9

Просто сделайте sleep(5) (включая unistd.h). Вы можете использовать его как это:

// do some work here 
someFunction();  

// have a rest 
sleep(5); 

// do some more work 
anotherFunction(); 

Если вы делаете работу внутри цикла, вы можете сделать (в том числе time.h):

// set the end time to the current time plus 5 seconds 
time_t endTime = time(NULL) + 5; 

while (time(NULL) < endTime) 
{ 
    // do work here. 
} 
+0

Имейте в виду, что цикл while будет принимать не менее * 5 секунд, это может занять более 5 секунд, если работа внутри цикла занимает много времени. – dreamlax

+0

Это интересно, но я не хочу делать системный вызов внутри петли –

+0

@the_drug: Есть ли причина? – dreamlax

9

Попробуйте использовать часы().

#include <time.h> 

clock_t start = clock(); 

while (1) 
{ 
    clock_t now = clock(); 
    if ((now - start)/CLOCKS_PER_SEC > 5) 
     break; 

    // Do something 
} 
+1

'clock()' возвращает количество используемого времени процессора, а не в реальном времени. – dreamlax

0

Не тестировался; разрешение очень грубое.

#include <time.h> 
#define RUNTIME 5.0 /* seconds */ 

double runtime = 0; 
double start = clock(); /* automatically convert clock_t to double */ 
while (runtime < RUNTIME/CLOCKS_PER_SEC) { 
    /* work */ 
    runtime = clock() - start; 
} 

Если/* работа */занимает более 5 секунд, цикл займет более 5 секунд.

Если/* работа */занимает 1,2 секунды, то цикл будет выполняться приблизительно 5 раз в общей сложности 6 секунд

+0

Просто любопытно, зачем использовать 'double', а не' clock_t'? – dreamlax

+0

Потому что 'clock_t' является« арифметическим типом ». Нет гарантии, что он может содержать дробные значения (например: 0,5) ... и я чувствую себя лучше, используя 'double' – pmg

+0

Кроме того, после ознакомления с соответствующим [spec] (http://www.opengroup.org/onlinepubs/ 009695399/functions/clock.html), похоже, что 'clock()' вернет количество используемого времени процессора, а не в реальном времени. – dreamlax

1

Прежде всего, рассмотрим, используя функцию sleep, если это возможно. Если вы должны сделать фактическую работу в течение определенного периода времени, который я считаю маловероятным, следующий некрасиво решение будет работать:

#include <signal.h> 
int alarmed = 0; 
void sigh(int signum) { 
    alarmed = 1; 
} 
int main(void){ 
    /* ... */ 
    signal(SIGALRM, &sigh); 
    alarm(5); // Alarm in 5 seconds 
    while(!alarmed) { 
     /* Do work */ 
    } 
    /* ... */ 
} 

Раствор с помощью time.h также можно было бы, и, возможно, проще и/или более точным, в зависимости от контекста:

#include <time.h> 
int main(void){ 
    /* ... */ 
    clock_t start = clock(); 
    while(clock() - start < 5 * CLOCKS_PER_SEC) { 
     /* Do work */ 
    } 
    /* ... */ 
} 
+0

Это должно быть 'void sigh (int signum)', правильно? –

+0

Первое решение - это тот, который я фактически использую. Дело в том, что я должен использовать «изменчивые» переменные в моем цикле, иначе они будут потеряны. Но использование изменчивых переменных замедляет мой цикл. –

+0

@ Оли: Должно. Теперь я отредактирую - на самом деле не обращал внимания вчера вечером;) – You

0

Если вы не хотите, чтобы вызвать время получить функцию каждый раз через петлю и в системе, которая имеет alarm (POSIXes как Unix, Linux, BSD ...) вы можете do:

статический volatil e int timeout = 0;

void handle_alrm(int sig) { 
    timeout = 1; 
} 

int main(void) { 
    signal(SIGALRM, handle_alrm); 
    ... 
    timeout = 0; 
    alarm(5); 
    while (!timeout) { 
     do_work(); 
    } 
    alarm(0); // If the signal didn't fire yet we can turn it off now. 
    ... 

Сигналы могут иметь другие побочные эффекты (например, удары вас из системных вызовов). Вы должны изучить их, прежде чем полагаться на них.

+0

Нужно ли время ожидания быть неустойчивым? И если это так, должно ли это быть 'sig_atomic_t'? Я спрашиваю, потому что каждый раз, когда я что-то делаю с сигналами, мне всегда нужно все передумать ... –

+0

В этом контексте я бы использовал оба; Я могу сделать аргумент, что либо/оба они не нужны, но они не нанесут никакого вреда, и они * могут * сохранить вашу задницу. – zwol

+0

@Steve: Я собирался сделать это 'sig_atomic_t', но я подумал, что« это может быть недоступно в Windows », а затем забыл вернуться и изменить его, когда понял, что« будильник »также может быть недоступен. – nategoose