|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Dusky_Joe
Anmeldungsdatum: 07.01.2005 Beiträge: 1007 Wohnort: Regensburg/Oberpfalz
|
Verfasst am: 18.08.2005, 22:36 Titel: MUTEXCREATE und VA_ARG: Befehlserklärung OK? |
|
|
Hi Community!
Ich habe gerade die Eintrag MUTEXCREATE und VA_FIRST zur Referenz hinzugefügt, und möchte nun euere Meinung dazu hören, da es sich doch um recht wichtige oder zumindest komplizierte Kapitel handelt.
Dusky_Joe hat Folgendes geschrieben: | MUTEXCREATE
Syntax: MUTEXCREATE
Typ: Funktion
Kategorie: Programmorganisation
Erstellt einen Mutex, und gibt einen Handle zu diesem zurück.
Der Rückgabewert ist eine INTEGER-Variable, die einen Mutex eindeutig identifiziert. Über sie wird später auf den Mutex zugegriffen.
Mutex (englisch Mutual Exclusion, deutsch gegenseitiger Ausschluss) bezeichnet Verfahren,
mit denen verhindert wird, dass nebenläufige Prozesse gleichzeitig auf Daten
zugreifen und so unter Umständen inkonsistente Zustände herbeiführen.
(Auszug aus Wikipedia; siehe http://de.wikipedia.org/wiki/Mutex)
Wenn zwei Threads (siehe THREADCREATE gleichzeitig versuchen, auf eine globale Variable
zuzugreifen, kann dies zu Problemen führen. Durch Mutexe kann dies verhindert
werden, indem ein Thread dazu gezwungen wird, darauf zu warten, dass ein anderer
Thread seinen Zugriff beendet hat.
Ein Mutex kann entweder gesperrt oder entsperrt sein. Wenn ein Thread versucht,
auf diesen Mutex zuzugreifen, muss er warten, bis dieser entsperrt wurde. Dazu
verwendet man MUTEXLOCK und MUTEXUNLOCK.
Auch das sperren eines Mutexes gilt als Zugriff; bei der Durchführung dieses
Vorgangs wird also auf die Entsperrung gewartet.
Beispiel (aus dem examples-Ordner Ihres freeBASIC-Verzeichnisses):
Code: | DEFINT a-z
OPTION EXPLICIT
DECLARE SUB consumer ( BYVAL param AS INTEGER )
DECLARE SUB producer ( BYVAL param AS INTEGER )
DIM SHARED produced AS INTEGER, consumed AS INTEGER
DIM consumer_id AS INTEGER, producer_id AS INTEGER
produced = MUTEXCREATE
consumed = MUTEXCREATE
IF( ( produced = 0 ) OR ( consumed = 0 ) ) THEN
PRINT "Error creating mutexes! Exiting..."
END 1
END IF
MUTEXLOCK produced
MUTEXLOCK consumed
consumer_id = THREADCREATE(@consumer)
producer_id = THREADCREATE(@producer)
IF( ( producer_id = 0 ) OR ( consumer_id = 0 ) ) THEN
PRINT "Error creating threads! Exiting..."
END 1
END IF
THREADWAIT consumer_id
THREADWAIT producer_id
MUTEXDESTROY consumed
MUTEXDESTROY produced
SLEEP
'------------------------------------------------------------------------------'
SUB consumer ( BYVAL param AS INTEGER )
DIM i AS INTEGER
FOR i = 0 TO 9
MUTEXLOCK produced
PRINT ", consumer gets:", i
MUTEXUNLOCK consumed
NEXT i
END SUB
SUB producer ( BYVAL param AS INTEGER )
DIM i AS INTEGER
FOR i = 0 TO 9
PRINT "Producer puts:", i;
MUTEXUNLOCK produced
MUTEXLOCK consumed
NEXT i
END SUB |
Zunächst sind beide Mutexe gesperrt. Wenn der Prozessor zuerst versucht,
den Thread 'consumer' auszuführen, stößt er auf das Hindernis,
das 'produced' bereits gesperrt ist. Es kann erst dann gesperrt werden, wenn es
entsperrt wurde. Der Prozessor wartet also mit der Ausführung des Threads
'consumer', und setzt mit der Ausführung der anderen Threads in der
Warteliste fort. (Hier: Thread 'producer').
'producer' greift zuerst auf keinen Mutex zu, und wird sofort durchgeführt.
Dann wird 'produced' entsperrt - 'consumer' kann also ausgeführt werden. Wenn
der Prozessor dennoch zuerst veruscht, die Schleife in 'producer' einmal zu durchlaufen,
stößt er auf das Hindernis, dass 'consumed' bereits gesperrt ist. Er muss
also darauf warten, dass dieser Mutex von 'consumer' entsperrt wird.
Siehe auch:
MUTEXDESTROY, MUTEXLOCK, MUTEXUNLOCK THREADCREATE, THREADWAIT |
Vor allem bin ich mir hier nicht sicher, ob ich den Wikipedia-Ausschnitt beibehalten sollte.
http://de.wikipedia.org/wiki/Wikipedia:Lizenzbestimmungen
Diese Url erlaubt mir eindeutig, den Ausschnitt zu veröffentlichen, aber...
Abgesehen davon, ist dieser Eintrag verständlich?
Ich hatte nämlich eigentlich nicht vor, bei den anderen MUTEX-Befehlen noch einmal genauer darauf einzugehen. Bei MUTEXLOCK stünde dann lediglich etwas in dieser Art:
Zitat: | MUTEXLOCK sperrt den Zugriff auf einen Mutex. Siehe MUTEXCREATE |
Und eben genauere Hinweise zur Syntax. (MUTEXLOCK Mutex, wobei 'Mutex' der Handle zum mit MUTEXCREATE erstellten Mutex ist.)
Für VA_FIRST gelten eigentlich die selben Fragen. Ist dieser Eintrag...
...verständlich?
...korrekt?
... äh...
Dusky_Joe hat Folgendes geschrieben: | VA_FIRST
Syntax: VA_FIRST()
Typ: Funktion
Kathegorie: Programmorganisation
Gibt einen Pointer auf den ersten Parameter einer Prozeduren zurück.
Unter freeBASIC ist es möglich Prozeduren zu erstellen, die keine
festgelegte Parameterliste besitzen. Diesen Prozeduren darf eine beliebig Lange
Parameterliste übergeben werden, und die Parameter dürfen von jedem
Datentyp sein. Eine solche Liste wird variable Parameterliste genannt.
Um dies zu ermöglichen, verwendet man bei DECLARE und im Prozedurheader diese
Syntax:[DECLARE] { SUB | FUNCTION } (['normaleParameter'], ...)
'normaleParameter' ist dabei eine normale Parameterliste, wie bei DECLARE
erklärt.
Das '...' leitet dabei die variable Parameterliste ein.
Bei dieser Form der Übergabe geht aber die Information verloren, um welchen
Datentyp es sich in der variablen Liste handelt, bzw. wie viele Parameter übergeben
wurden. Daher werden oft sogenannte Format-Strings in der normalen
Parameterliste übergeben, in denen beschrieben wird welche Parameter übergeben wurden.
Dieser Format-String darf jedes beliebige Format besitzen, da der Programmierer
die Parameterübergabe komplett selbst übernimmt. Der String muss ihm
lediglich die Informationen liefern, die er braucht, um die Werte aus der
beliebigen Parameterliste herauszulesen.
VA_ARG wird dazu benutzt, um den Wert eines Parameters zu ermitteln.
VA_NEXT updatet den von VA_FIRST zurückgegebenen Pointer, so dass
er auf das nächste Argument der beliebigen Parameterliste zeigt.
Beispiel (aus dem examples-Ordner ihres freeBASIC-Verzeichnisses):
Code: | OPTION EXPLICIT
DECLARE SUB myprintf CDECL (fmtstr AS STRING, ...)
DIM s AS STRING
s = "bar"
myprintf( "Integer=%i, Longint=%l Single=%f, Double=%d, String=%s, String=%s", _
1, 1LL SHL 32, 2.2!, 3.3#, "foo", s )
PRINT
SLEEP
'------------------------------------------------------------------------------'
SUB myprintf CDECL (fmtstr AS STRING, ...)
DIM AS ANY PTR arg
DIM AS ZSTRING PTR p
DIM AS INTEGER i, char
' Ermittle Pointer auf das erste Argument der variablen Parameterliste
arg = VA_FIRST()
' bearbeite jedes Zeichen des Format-Strings einzeln
p = STRPTR( fmtstr )
FOR i = 0 TO LEN( fmtstr )-1
char = *p
p += 1
' ist es ein Formatierungs-Zeichen?
IF( char = ASC( "%" ) ) THEN
' um welchen Typ handelt es sich?
char = *p
p += 1
' Das variable Argument abhängig vom Typ ausgeben
SELECT CASE char
CASE ASC( "i" )
PRINT STR$( VA_ARG( arg, INTEGER ) );
' im Gegensatz zu C muss VA_NEXT benutzt werden, um den Pointer zu
' updaten, damit er nach einsatz von VA_ARG auf den n䣨sten
' Parameter zeigt.
arg = VA_NEXT( arg, INTEGER )
CASE ASC( "l" )
PRINT STR$( VA_ARG( arg, LONGINT ) );
arg = VA_NEXT( arg, LONGINT )
CASE ASC( "f" )
PRINT str$( VA_ARG( arg, SINGLE ) );
arg = VA_NEXT( arg, SINGLE )
CASE ASC( "d" )
PRINT str$( VA_ARG( arg, DOUBLE ) );
arg = VA_NEXT( arg, DOUBLE )
CASE ASC( "s" )
' Strings werden BYVAL ?ben, daher ist ihre L䮧e unbekannt
PRINT *VA_ARG( arg, zstring PTR );
arg = VA_NEXT( arg, zstring PTR ) '' /
END SELECT
' normales Zeichen, also ausgeben, wie es ist.
ELSE
PRINT chr$( char );
END IF
NEXT
END SUB |
Siehe auch:
VA_ARG, VA_NEXT,
DECLARE, SUB, FUNCTION,
Datentypen, Prozeduren |
Auch hier wollte ich unter VA_ARG und VA_FIRST nur auf VA_FIRST verweisen, da eigentlich schon alles wichtige erklärt wurde.
Postet also hier bitte Verbesserungsvorschläge.
Danke!
Have a nice day
Ciao _________________ fully biological degradable
Once, the big wave arrives, you've got two ways, you can go:
Either, you ride it, or you don't do.
But, if you don't ride, you'll never know wether you'd have gone wet. |
|
Nach oben |
|
|
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1875 Wohnort: D59192
|
Verfasst am: 23.08.2005, 18:45 Titel: |
|
|
Hallo Dusky_Joe,
lass die Erklärungen dieser Befehle so wie du sie hier angegeben hast.
Da das Befehle sind an die sich geübterere Basicer trauen, solte denen dann auch die Fachbegriffe und Beispiele verständlich sein.
Gruß
Volta |
|
Nach oben |
|
|
Mecki Igel
Anmeldungsdatum: 10.09.2004 Beiträge: 985 Wohnort: Niederbayern
|
|
Nach oben |
|
|
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1875 Wohnort: D59192
|
Verfasst am: 23.08.2005, 20:01 Titel: |
|
|
Mmmm???
Mecki, jetzt versteh ich nur "Bahnhof.."
Zitat: | Ist es nicht der Sinn der Referenz Wissen zu verbreiten? Also ich versteh dich da jetzt nicht so ganz, Volta. |
Ich finde die Erklärungen von Dusky_Joe gut, so wie sie sind!
Weitere Verbesserungsvorschläge habe ich nicht!
Weiter ins Detail zu gehen finde ich überflüssig!
Nichts anderes wollte und habe ich im obigen Beitrag gesagt.
Gruß
Volta |
|
Nach oben |
|
|
Mecki Igel
Anmeldungsdatum: 10.09.2004 Beiträge: 985 Wohnort: Niederbayern
|
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|