Boost interprocess vs. Win32API: Unterschied zwischen den Versionen

Aus Software Entwicklung Projekte
Wechseln zu: Navigation, Suche
Zeile 1: Zeile 1:
 +
Zurück zur [[Windows Entwicklung]]
 +
 
= Boost interprocess =
 
= Boost interprocess =
  

Version vom 18. Juni 2015, 12:35 Uhr

Zurück zur Windows Entwicklung

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.