Änderungen
Die Seite wurde neu angelegt: „= Boost interprocess = Folgende C++ Klassen habe ich unter VS2013/Win8.1/64bit eingesetzt um Threads zu synchronisieren bzw. Code zu schützen. Eingesetzt ha…“
= 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).
<pre>
boost::interprocess::interprocess_mutex MyMutex;
boost::interprocess::interprocess_condition MyCondition;
boost::interprocess::interprocess_semaphore MySemaphore;
</pre>
Dabei habe ich komplette Funktionen mittels scoped_lock gesperrt:
<pre>
boost::interprocess::scoped_lock<boost::interprocess::interprocess_recursive_mutex> lock(reentrant_block);
</pre>
Desweiteren habe ich Signale für bestimmte Aktionen über die Condition ausgelösst:
<pre>
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));
...
}
</pre>
=== 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.
<pre>
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);
}
</pre>
== 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.
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).
<pre>
boost::interprocess::interprocess_mutex MyMutex;
boost::interprocess::interprocess_condition MyCondition;
boost::interprocess::interprocess_semaphore MySemaphore;
</pre>
Dabei habe ich komplette Funktionen mittels scoped_lock gesperrt:
<pre>
boost::interprocess::scoped_lock<boost::interprocess::interprocess_recursive_mutex> lock(reentrant_block);
</pre>
Desweiteren habe ich Signale für bestimmte Aktionen über die Condition ausgelösst:
<pre>
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));
...
}
</pre>
=== 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.
<pre>
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);
}
</pre>
== 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.