Я пытался придумать кроссплатформенную альтернативу sleep(), но мой код не совсем работает.

Я делаю небольшую программу на С++ для начинающих, основанную на игре snap.

Когда я вывожу объекты карты на консоль, из-за скорости обработки компьютеров, естественно, просто появляется весь список карт, которые были розданы. Я подумал, что было бы неплохо, если бы я мог ставить паузу между раздачей каждой карты, чтобы человек мог фактически наблюдать за раздачей каждой карты. Поскольку я всегда работаю как с Linux, так и с Windows и уже включил ‹ ctime >, я придумал это небольшое решение:

for(;;){
            if( (difftime(time(0),lastDealTime)) > 0.5f){ //half second passed
                cout << currentCard <<endl;
                lastDealTime = time(0);
                break;
            }
        }

Сначала я подумал, что это сработало, но потом, когда я попытался ускорить процесс раздачи позже, я понял, что изменение контрольного значения 0,5 (я стремился к раздаче карт каждые полсекунды), похоже, не имело никакого эффекта. Я попытался изменить его на раздачу каждые 0,05 секунды, и это не имело никакого значения, карты по-прежнему выдавались каждую секунду, я думаю.

Любые наблюдения относительно того, почему это не будет работать? Спасибо!


person Holly    schedule 31.01.2012    source источник
comment
Кроме того, ваша реализация представляет собой цикл занятости, а это означает, что программа будет вращаться и использовать все ресурсы ЦП, которые она может получить, пока ждет, потенциально замедляя все остальное. Вот почему вы должны использовать сон в той или иной форме.   -  person Supr    schedule 31.01.2012
comment
ага спасибо за информацию буду помнить :)   -  person Holly    schedule 31.01.2012
comment
См., кстати, en.wikipedia.org/wiki/Busy_waiting :)   -  person Supr    schedule 31.01.2012
comment
Если вам нравится писать код, переносимый как для Windows, так и для Linux, вам следует ознакомиться с библиотеками Boost (boost.org). ). Но вы должны уточнить у своего преподавателя, можете ли вы использовать его в своих заданиях.   -  person Emile Cormier    schedule 31.01.2012


Ответы (4)


time() и difftime() имеют разрешение в секунду, поэтому их нельзя использовать для управления интервалами меньше секунды; даже для интервалов в секунду их нельзя использовать, поскольку джиттер может достигать и секунды.

В этом случае решение состоит в том, чтобы определить своего рода класс таймера с независимым от системы интерфейсом в заголовочном файле, но зависящими от системы исходными файлами; в зависимости от системы вы компилируете один исходный файл или другой. И в Windows, и в Linux есть способы управления временем с более высоким разрешением.

person James Kanze    schedule 31.01.2012

Разрешение time() составляет одну секунду, т. е. возвращаемое значение представляет собой целое число секунд. Вы никогда не увидите разницу меньше секунды.

usleep() находится в стандартной библиотеке C — у него разрешение в микросекундах, так что используйте его.

person Ernest Friedman-Hill    schedule 31.01.2012
comment
ааа, я вижу, как глупо с моей стороны! У меня сложилось впечатление, что usleep() не будет работать на машине с Windows. Спасибо за информацию! - person Holly; 31.01.2012
comment
Думаю, @Holly usleep() не будет работать в Windows. Есть Sleep() (разрешение системного таймера около 15 миллисекунд), и вы можете увеличить его с помощью timeBeginPeriod(). - person lapk; 31.01.2012
comment
usleep — это стандартная функция POSIX, не являющаяся частью стандартной библиотеки C. Стандартная библиотека C вообще не имеет отношения к многопоточности. - person Emile Cormier; 31.01.2012
comment
@EmileCormier, так что просто для ясности, нет функции сна, которая будет работать как в Windows, так и в Linux (если я, очевидно, не сделаю ее сам)? Спасибо, что прояснили для меня эту дезинформацию. - person Holly; 31.01.2012
comment
@Holly: единственный способ использовать ту же функцию — использовать функции C++ 11 или стороннюю библиотеку, например Boost. В Windows собственная функция Win32 API для перехода в спящий режим — Sleep. С С++ 11 вы можете использовать std::this_thread::sleep. С Boost вы можете использовать boost::this_thread::sleep. - person Emile Cormier; 31.01.2012
comment
К сожалению, в C++11 это std::this_thread::sleep_for или std::this_thread::sleep_until, согласно en.cppreference.com/w/ cpp/поток . - person Emile Cormier; 31.01.2012

Если вы хотите убедиться, что карты раздаются именно с тем интервалом, который вы запрашиваете, вам, вероятно, также следует создать класс таймера. Мы используем:

В Windows используйте QueryPerformanceFrequency чтобы получить системное время и QueryPerformanceCounter, чтобы получить отметки

На Mac Carbon используйте DurationToAbsolute, чтобы получить время тика системы, и UpTime, чтобы получить тики.

В Linux используйте clock_gettime.

Для сна использовать:

Одна Windows использует Sleep();

На Mac Carbon используйте MPDelayUntil();

В Linux используйте nanosleep();

person Carey Hickling    schedule 31.01.2012

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

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

person CashCow    schedule 31.01.2012