Boost interprocess vs. Win32API
Zurück zur Windows Entwicklung
Inhaltsverzeichnis
Boost interprocess
Folgende C++ Klassen habe ich unter VS2013/Win8.1/64bit eingesetzt um Threads zu synchronisieren bzw. Code zu schützen.
Eingesetzt habe ich die Boost 1.58 (Stand 18.06.2015).
boost::interprocess::interprocess_mutex MyMutex; boost::interprocess::interprocess_condition MyCondition; boost::interprocess::interprocess_semaphore MySemaphore;
Dabei habe ich komplette Funktionen mittels scoped_lock gesperrt:
boost::interprocess::scoped_lock<boost::interprocess::interprocess_recursive_mutex> lock(reentrant_block);
Desweiteren habe ich Signale für bestimmte Aktionen über die Condition ausgelösst:
void func1() { ... MyCondition.post(); ... } void func2() { ... boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(cond_read_mutex); bool ret = cond_read_possible.timed_wait(lock, boost::get_system_time() + boost::posix_time::milliseconds(timeoutMS)); ... }
Ergebnis Boost 1.58
Der entwickelte Serverprozess hatte eine CPU Last von 2.5%, obwohl dieser im Leerlauf war. Die Last ist einfach nur durch das Warten begrenzt durch einen timeout entstanden.
Mögliches weiteres Problem: Was bewirkt eine Zeitumstellung bei einem Timeout mit absoluter Zeitangabe?
Win32 API
Ich habe alle Stellen ausgetauscht gegen SRWLOCK und CONDITION_VARIABLE, die seit Windows 2008 bzw. Vista unterstützt werden (nicht unter XP oder W2003 bzw. älter). Der neue Code ist fast identisch zu dem Alten.
SRWLOCK reentrant_block SRWLOCK cond_write_srw; CONDITION_VARIABLE cond_write_possible; void Init() { InitializeSRWLock(&reentrant_block); InitializeSRWLock(&cond_write_srw); InitializeConditionVariable(&cond_write_possible); } void func_protected() { AcquireSRWLockShared(&reentrant_block); ... ReleaseSRWLockShared(&reentrant_block); } void func_signal() { WakeAllConditionVariable(&cond_write_possible); } void func_wait_signal() { AcquireSRWLockShared(&cond_write_srw); BOOL ret = SleepConditionVariableSRW(&cond_write_possible, &cond_write_srw, timeoutMS, CONDITION_VARIABLE_LOCKMODE_SHARED); ... // Hier muss noch ret ausgewertet werden ... // geschützter Code ReleaseSRWLockShared(&cond_write_srw); }
Ergebnis Win32API
Die Last des Servers im Leerlauf ist auf unter 0.01% gesunken.
Ein Test unter Last hat ergeben, dass der gesamte Prozess um 80% schneller abläuft. Dies ist aber auch ein Hinweis, dass ich in meinem Design zu sehr von schnellen Locks abhängig bin.