Ich glaube, es ist eine Race Condition, obwohl eine sehr seltene. Die Implementierung von condition_variable :: timed_wait() mit einer Dauer konvertiert einfach den Wert in eine system_time mit get_system_time() + wait_duration. Wenn sich die Systemzeit zwischen dem Zeitpunkt ändert, an dem get_system_time() aufgerufen wird, und der berechneten Wartezeitendezeit in einen tickbasierten Zähler für den zugrunde liegenden Betriebssystemaufruf konvertiert wird, ist die Wartezeit falsch.
diese Idee zu testen, auf Windows, schrieb ich ein einfaches Programm mit einem Thread all 100ms eine Ausgabe zu erzeugen, wie folgt aus:
for (;;)
{
boost::this_thread::sleep(boost::get_system_time() +
boost::posix_time::milliseconds(100));
std::cout << "Ping!" << std::endl;
}
Ein anderer Thread die Systemzeit wieder eine Minute lang in der Vergangenheit einstellt jeder 100ms (dieser Thread verwendet die OS-Ebene "Sleep()" Aufruf, die Conversions Systemzeit vermeidet): "Ping"
for (;;)
{
Sleep(100);
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
FILETIME fileTime;
SystemTimeToFileTime(&sysTime, /*out*/&fileTime);
ULARGE_INTEGER fileTime64 = (ULARGE_INTEGER(fileTime.dwHighDateTime) << 32) |
fileTime.dwLowDateTime;
fileTime64 -= 10000000 * 60; // one minute in the past
fileTime.dwHighDateTime = (fileTime64>>32) & 0xFFFFFFFF;
fileTime.dwLowDateTime = fileTime64 & 0xFFFFFFFF;
FileTimeToSystemTime(&fileTime, /*out*/&sysTime);
SetSystemTime(&sysTime);
}
Der erste Thread, obwohl die Ausgabe soll alle 100 Millisekunden, ziemlich schnell abgeschlossen.
Sofern ich etwas vermisse, scheint Boost keine APIs zur Verfügung zu stellen, die dieses Problem interner Konvertierungen zur Systemzeit vermeiden und Apps für äußere Änderungen der Uhr anfällig machen.
@Roddy: OK, aber der Ordnung halber Ihre Antwort meine experimentellen Ergebnisse zu der Zeit angepasst. – indiv