Frage

Ich fand bereits mit einer anderen Frage, dass Windows/MingW nicht die nanosleep() und setitimer() alternativen zu den veralteten usleep().Aber mein Ziel ist zu lösen alle Warnungen, die cppcheck mir bietet, einschließlich der usleep() style Warnungen.

Also, gibt es eine Problemumgehung, um irgendwie zu vermeiden, usleep() auf Windows ohne mit cygwin oder der Installation lädt der neue Abhängigkeiten/Bibliotheken?Vielen Dank.

War es hilfreich?

Lösung

usleep() Arbeitet mit Mikrosekunden. In Windows sollten Sie eine Mikrosekunde -Vorbettung erhalten, die Sie verwenden sollten QueryperformanceCounter () WinAPi -Funktion. Hier Sie können feststellen, wie diese Vorbettung mit dieser Nutzung erhalten.

Andere Tipps

Ich habe diesen Code von (ursprünglich von hier):

#include <windows.h>

void usleep(__int64 usec) 
{ 
    HANDLE timer; 
    LARGE_INTEGER ft; 

    ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time

    timer = CreateWaitableTimer(NULL, TRUE, NULL); 
    SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); 
    WaitForSingleObject(timer, INFINITE); 
    CloseHandle(timer); 
}

Beachten Sie, dass SetWaitableTimer() Verwendet "100 Nanosekundenintervalle ... positive Werte zeigen die absolute Zeit an. ... Negative Werte geben die relative Zeit an." und das "Die tatsächliche Timergenauigkeit hängt von der Fähigkeit Ihrer Hardware ab."

Wenn Sie einen C ++ 11 -Compiler haben, können Sie verwenden Dies tragbare Version:

#include <chrono>
#include <thread>
...
std::this_thread::sleep_for(std::chrono::microseconds(usec));

Ein großes Lob an Howard Hinnant, der das Erstaunliche entworfen hat <chrono> Bibliothek (und deren Antwort unten verdient mehr Liebe.)

Wenn Sie kein C ++ 11 haben, aber Boost haben, können Sie dies tun Dies stattdessen:

#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
...
boost::this_thread::sleep(boost::posix_time::microseconds(usec));

Neue Antwort für eine alte Frage:

Begründung für die neue Antwort: Tools / OSS wurden so aktualisiert, dass es jetzt eine bessere Wahl gibt als bei der Frage, als die Frage ursprünglich gestellt wurde.

Die c ++ 11 <chrono> und <thread> STD -Header sind seit mehreren Jahren im VS Toolset. Mit diesen Headern wird dies am besten in C ++ 11 als:

std::this_thread::sleep_for(std::chrono::microseconds(123));

Ich verwende Mikrosekunden nur als Beispieldauer. Sie können die Dauer nutzen, die zweckmäßig ist:

std::this_thread::sleep_for(std::chrono::minutes(2));

Mit C ++ 14 und einigen verwendeten Anweisungen kann dies ein bisschen kompakter geschrieben werden:

using namespace std::literals;
std::this_thread::sleep_for(2min);

oder:

std::this_thread::sleep_for(123us);

Dies funktioniert definitiv auf VS-2013 (Modulo the Chrono-Literale). Ich bin mir nicht sicher über frühere Versionen von Vs.

Millisecond regime der Sleep() Funktion ist gut beschrieben und gut verständlich.Es tut nichts unvorhersehbar.Manchmal ist die Funktion wird beschuldigt durchführen unberechenbar, d.h.Rückkehr, bevor die Verzögerung abgelaufen ist.Ich muss sagen, dass das falsch ist.Eine sorgfältige Untersuchung wird bestätigen, dass sein Verhalten ist absolut vorhersehbar.Das problem ist nur dass es viel zu Lesen über es, und die meisten von es ist kiddish.Es wird auch oft gesagt, dass windows es kein Echtzeit-OS.Aber solche Kommentare nicht etwas beitragen, außerdem solche Kommentare werden verwendet, um zu verstecken das fehlen von wissen.Es macht mich irgendwie wütend, dass nicht einmal microsoft merkt dies und bietet eine bessere Dokumentation.

Allerdings, ohne zu übertreiben, dieses kleine Antwort:Die sleep() Funktion genau ist, wenn verwendet in einem richtigen Weg, und wenn man seine Eigenschaften.Besondere Aufmerksamkeit gewidmet werden, um zu schlafen(0).Dies ist ein sehr leistungsfähiges Werkzeug, besonders wenn Sie zusammen mit Prozess-Prioritätsklasse, thread-Priorität, multimedia timer-Einstellungen, und Prozessor Affinität Maske.

Also in der Regel eine wahre schlafen können durchgeführt werden, leicht und sicher nach unten zu den Systemen interrupt-Periode.Wenn es darum geht, schläft kürzer als die interrupt-Periode spinning erforderlich ist.Eine höhere Auflösung Zeitquelle verwendet werden, oder in drehen, kürzer in der Zeit.Die häufigste Quelle für diese ist die performance counter. QueryPerformanceCounter(*arg) erzielt ein Inkrementieren *arg. QueryPerformanceFrequency(*arg) liefert die Frequenz, bei der die performance-counter-Schritten.Dies ist in der Regel in den MHz-regime und variiert, abhängig von der zugrunde liegenden hardware.Einer Frequenz im MHz-Bereich bietet Mikrosekunde Auflösung an.Diese Weise etwas von der hohen Auflösung können verwendet werden, um zu warten, bis die gewünschte Zeitspanne ablaufen.Allerdings ist die Genauigkeit dieser untersucht werden sorgfältig:Die OS-gibt die Leistung Zähler Frequenz als eine Konstante.Das ist falsch!Da die Frequenz erzeugt werden, die ein physisches Gerät, es ist immer eine offset-und es auch nicht ein konstant.Es hat thermische drift.Moderne Systeme haben weniger drift.Aber wenn die thermische drift ist nur 1ppm, wird der Fehler 1us/s.Der offset kann leicht mehrere 100.Ein offset von 100 in 1 MHz entspricht 100µs/s.

Wenn ein thread muss warten, für jede Zeit, in hoher Auflösung, es soll die Einrichtung einer service-thread.Beide thread teilen ein benanntes Ereignis.Der service-thread sollen schlafen, bis 1 interrupt-Periode Voraus, die gewünschte sleep-Verzögerung, und drehen auf die performance-Zähler für die verbleibenden Mikrosekunde.Wenn der service-thread erreicht die Letzte Zeit, es die benannte Ereignis und enden.Der aufrufende thread wird aufwachen, denn es war zu warten, für das benannte Ereignis durch eine wait-Funktion.

Zusammenfassung:

  • Schlaf ist gut verstanden, aber schlecht dokumentiert.
  • Ein service thread nachahmen können schläft in hoher Auflösung.
  • Solch einen service thread coulb werden esablished als system-wide service.
  • Genauigkeit der Leistungsindikator betrachtet werden sorgfältig.Eine Kalibrierung erforderlich ist.

Weitere detaillierte Informationen finden Sie auf der Windows Timestamp Projekt

Es hängt davon ab, welche Granularität Sie brauchen. Wenn Sie über Millisekunden sprechen, wird die Win32 -Schlaffunktion den Job erledigen - siehe http://msdn.microsoft.com/en-us/library/ms686298%28v=vs.85%29.aspx. Wenn Sie über Mikrosekunden sprechen, gibt es keine einfache Möglichkeit, dies zu tun, und Sie hätten das Glück, diese Art von Timer -Auflösung unter Windows (was kein RTOs ist) oder unter Linux zu erhalten.

ich fand Dieser Blog -Beitrag darüber. Es verwendet QueryPerformanceCounter. Die Funktion gepostet:

#include <windows.h>

void uSleep(int waitTime) {
    __int64 time1 = 0, time2 = 0, freq = 0;

    QueryPerformanceCounter((LARGE_INTEGER *) &time1);
    QueryPerformanceFrequency((LARGE_INTEGER *)&freq);

    do {
        QueryPerformanceCounter((LARGE_INTEGER *) &time2);
    } while((time2-time1) < waitTime);
}

Ich hoffe das hilft ein bisschen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top