Download file - eLib
Transcript
kann gesperrt und entsperrt werden. Ist der Mutex gesperrt, kann er nicht erneut gesperrt werden. Dadurch, dass ich zu Beginn jeder Methode des Ringpuffers diesen Mutex sperre und am Ende wieder entsperre, garantiere ich, dass sich in dem Bereich zwischen diesen beiden Operationen nie mehrere Threads befinden. Sollte in diesem Bereich jedoch eine Exception 53 ausgelöst werden, sodass die Methode nicht bis zum Ende ausgeführt wird, bleibt der Ringpuffer gesperrt. Daher habe ich die manuelle Sperrung und Entsperrung durch die Verwendung der, ebenfalls in der OSLib implementierten, Klasse Lock ersetzt. Einem Lock wird bei der Instanziierung durch den Konstruktor ein Mutex übergeben. Solange das Lock gültig ist, bleibt der Mutex gesperrt. Erst in seinem Destruktor gibt das Lock den Mutex wieder frei. Ich erzeuge also am Anfang einer jeden Methode des Ringpuffers eine lokale Variable des Typs Lock auf seinem Mutex. Sobald die Funktion verlassen wird, also auch im Falle einer Exception, verliert das Lock seine Gültigkeit und gibt den Mutex wieder frei. Zur Verifizierung des threadsicheren Ringpuffers habe ich einen entsprechenden Testfall implementiert. Er enthält zwei Threads, die sich einen Ringpuffer teilen. Der eine Thread schreibt die Zahlen von 0 bis 100 in den Ringpuffer. Der andere Thread liest die Daten aus dem Ringpuffer aus und vergleicht, ob auch wirklich die Zahlen 0 bis 100 übertragen wurden. Nur wenn alle Werte korrekt übertragen wurden, gilt der Test als bestanden. Die Kapazität des Puffers ist hierbei mit maximal drei Elementen bewusst klein gewählt, um die Randbedingungen eines vollen und eines leeren Speichers zu provozieren. 53 Eine solche Ausnahmebehandlung tritt im Programmablauf dann auf, wenn ein unerwartetes Ereignis aufgetreten ist. Beispiele hierfür sind der Abbruch einer Netzwerkverbindung oder der versuchte Zugriff auf einen nicht zugreifbaren Speicherbereich. Integration und Evaluierung eines Testboards zur Echtzeit-3D-Verarbeitung 51