функция сна, потребление процессора - PullRequest
1 голос
/ 20 октября 2011

От имени, извините за мой далеко не идеальный английский.

Я недавно написал своего демона для Linux (точнее, маршрутизатора OpenWRT) на C ++, и у меня возникла проблема.

Ну, там есть несколько потоков, по одному на каждое открытое TCP-соединение, основной поток ожидает новых TCP-соединений и, как я это называю, командный поток для проверки состояния.

Все работает нормально, но мой процессор всегда на 100%. Я теперь это из-за кода командира:

void *CommanderThread(void* arg)
{
    Commander* commander = (Commander*)arg;
    pthread_detach(pthread_self());
    clock_t endwait;

    while(true)
    {
        uint8_t temp;
        endwait = clock () + (int)(1 * CLOCKS_PER_SEC);
        for(int i=0;i<commander->GetCount();i++)
        {
            ptrRelayBoard rb = commander->GetBoard(i);
            if (rb!= NULL)
                rb->Get(0x01,&temp);
        }

        while (clock() < endwait);
    }
    return NULL;
}

Как видите, программа делает вещи каждые 1 с. Время здесь не критично. Я знаю, что процессор всегда проверяет, прошло ли время. Я пытался сделать что-то вроде этого: while (clock ()

Есть ли какое-либо решение, готовые функции (например, phread_sleep (20ms)) или обход моей проблемы? Может быть, я должен получить доступ к основным часам как-то?

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

Успевает ли заморозить весь процесс?

В настоящее время я отлаживаю его на Cygwin, но не думаю, что проблема здесь.

Спасибо за любые ответы и предложения, это очень ценится.

J.L.

Ответы [ 2 ]

2 голосов
/ 20 октября 2011

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

Если вы не пытаетесь приблизиться к точному времени, нет необходимости проверять часы ().

0 голосов
/ 29 октября 2011

Я решил это по-другому.

#include <sys/time.h>
#define CLOCK_US_IN_SECOND 1000000
static long myclock()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (tv.tv_sec * CLOCK_US_IN_SECOND) + tv.tv_usec;
}
void *MainThread(void* arg)
{
    Commander* commander = (Commander*)arg;
    pthread_detach(pthread_self());
    long endwait;

    while(true)
    {
        uint8_t temp;
        endwait = myclock() + (int)(1 * CLOCK_US_IN_SECOND);
        for(int i=0;i<commander->GetCount();i++)
        {
            ptrRelayBoard rb = commander->GetBoard(i);
            if (rb!= NULL)
                rb->Get(0x01,&temp);
        }
        while (myclock() < endwait)
            usleep((int)0.05*CLOCK_US_IN_SECOND);
    }
    return NULL;
}

Имейте в виду, что этот код уязвим для изменения времени во время выполнения. Не знаю, как это пропустить, но в моем случае это не очень важно.

...