C ++ Хотя цикл, usleep () / sleep (), как не использовать 90% процессорного времени? (Ubuntu 12.04)

Предположим, у меня есть код C ++, такой как

#include "myheaderfiles.h"//..some stuff
//...some more stuff
int main()
{
double milliseconds;
int seconds;
int minutes;
int timelimit=2;
...
...
//...code here that increments
//.....milliseconds,seconds, and minutes

while(minutes <=timelimit)
{
//...do stuff
if(milliseconds>500)
{
//...do stuff
//...every half second
} //end if
} //end while
}//end main

Программа будет работать нормально и будет делать то, что должна, но она будет использовать более 90% моего процессора.

Мне было предложено использовать usleep () в моем цикле while каждые 100 мс или около того, так как я все равно забочусь о том, чтобы делать что-то каждые 500 мс. Таким образом, он загружает процессор, когда его не нужно.

Так что я добавил его в свой цикл

   while(minutes <=timelimit)
{
//...do stuff
if(milliseconds>500)
{
//...do stuff
//...every half second
} //end if
usleep(100000);
} //end while

Он хорошо компилируется, но когда я его запускаю, программа зависает прямо во время сна и никогда не возвращается. Я где-то читал, что перед вызовом usleep необходимо очистить все буферы, поэтому я сбросил все файловые потоки, каты и т. Д. И т. Д. Все еще не повезло.

Я искал решение в течение 2 дней. Я тоже использовал sleep () без удачи.

Я нашел несколько альтернатив, но они кажутся сложными и добавят в мою программу много кода, который я не совсем понимаю, что усложнит его и сделает его беспорядочным, плюс он может не работать.

Я никогда не задумывался о циклах while () раньше, потому что большинство написанных мною программ предназначались для микроконтроллеров или FPGA, и это не проблема для загрузки процессора.

Если кто-то может помочь …. любые ресурсы, ссылки, книги? Благодарю.

3

Решение

Ваш подход несколько исходит из неправильного конца. Программа должен потреблять 90-100% ЦП до тех пор, пока у него есть что-то полезное (в противном случае он должен блокироваться, потребляя нулевой ЦП).
Сон между ними приведет к тому, что выполнение будет длиться дольше без веской причины, и потреблять больше энергии, чем просто выполнять работу как можно быстрее (при 100% ЦП), а затем полностью блокироваться, пока не будет доступно больше работы или до какой-либо другой важной вещи (например, половины Прошла секунда, если это важно для вас).

Имея это в виду, структурируйте вашу программу концептуально:

while(blocking_call() != exit_condition)
{
while(have_work)
do_work();
}

Кроме того, не спите во время выполнения, но используйте таймеры (например, setitimer) делать что-то через равные промежутки времени. Это будет не только более эффективным, но и намного более точным и надежным.

То, как именно вы это реализуете, зависит от того, насколько переносимым должно быть ваше программное обеспечение. В Ubuntu / Linux вы можете, например, использовать такие API, как epoll_wait с eventfd вместо того, чтобы писать обработчик сигнала для таймера.

2

Другие решения

Этот код работает, как и ожидалось для меня (хотя работает на OSX).

  #include <unistd.h>
#include <iostream>

int main() {
std::cout << "hello" << std::endl;

int i = 0;
while(i < 10) {
++i;
usleep(100000);
std::cout << "i = " << i << std::endl;
}
std::cout << "bye" << std::endl;
return 0;
}
0

Есть логическая проблема или, может быть, вы делаете несколько счетчиков? Поскольку вы сказали, что создали микроконтроллеры, я предполагаю, что вы пытаетесь использовать тактовые циклы в качестве метода подсчета при вызове системных таймеров? Кроме того, что вызывает у меня сомнения, если вам рекомендуется использовать usleep (x), почему вы используете double в течение миллисекунды? usleep (1) составляет 1 микросекунду == 1000 миллисекунд. Sleep (x) — это счетчик в x секунд, поэтому система приостанавливает текущее задание на x секунд.

#include <iostream>
#include <unistd.h>

using namespace std;

#define MILLISECOND 1000
#define SECOND 1000*MILLISECOND

int main(int argc, char *argv[]){
int time = 20;
int sec_counter = 0;
do{
cout<<sec_counter<<" second"<<endl;
usleep(SECOND);
sec_counter++;
} while(sec_counter<time+1);
return 0;
}

Если вы хотите использовать 500 мс, замените usleep (SECOND) на usleep (500 * MILLISECOND).
Я предлагаю вам использовать отладчик и пройтись по своему коду, чтобы увидеть, что происходит.

0
По вопросам рекламы [email protected]