 |
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 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 21.12.2012, 22:56 Titel: |
|
|
DEALLOCATE gibt einen mit ALLOCATE reservierten Speicherbereich wieder frei. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 22.12.2012, 00:26 Titel: |
|
|
Jo, habe ich inzwischen nachgelesen, wenn auch nicht ganz verstanden, aber egal.
Es steht allerdings auch da, dass es nicht unbedingt Thread-save ist.
Der Fehler mit der doppelten Anmeldung liegt zu 100% am Server, habe ich inzwischen getestet.
Hm... |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4704 Wohnort: ~/
|
Verfasst am: 22.12.2012, 00:46 Titel: |
|
|
Du belegst Speicher, und wenn du ihn nicht mehr brauchst, gibst du ihn wieder frei. Würdest du das nicht machen und immer wieder neuen Speicher belegen, würde dir auf Dauer der Speicherplatz ausgehen und das Programm abstürzen. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 23.12.2012, 01:56 Titel: |
|
|
@Puppetmaster
Dein vorgeschlagener Code
Code: |
Type MSG_Type
V_Next as MSG_Type Ptr
V_TSNEID as UInteger
'sollte V_Data nicht ein String sein? Aber auch als String
'funktioniert es nicht.
V_Data as UInteger
End Type
Dim Shared G_MSGF as MSG_Type Ptr
Dim Shared G_MSGL as MSG_Type Ptr
Sub TSNE_NewData(Byval V_TSNEID As Uinteger, Byref V_Data As String, Byval V_CallBackPtr As Client_Type Ptr)
MutexLock(G_ClientMux)
If G_MSGL <> 0 Then
G_MSGL->V_Next = CAllocate(SizeOf(MSG_Type))
G_MSGL = G_MSGL->V_Next
Else
G_MSGL = CAllocate(SizeOf(MSG_Type))
G_MSGF = G_MSGL
End if
With *G_MSGL
.V_TSNEID = V_TSNEID
.V_Data = V_Data
End With
MutexUnLock(G_ClientMux)
End Sub
Dim TPtr as MSG_Type Ptr
Do Until InKey() = Chr(27) 'oder wie auch immer die schleife aussieht
'...
MutexLock(G_ClientMux)
If G_MSGF <> 0 Then
TPtr = G_MSGF
With *TPtr
Verarbeite_Nachricht(.V_TSNEID, .V_Data)
End With
G_MSGF = TPtr->V_Next
DeAlloctae(TPtr)
End If
MutexUnLock(G_ClientMux)
'...
sleep 1, 1
Loop
|
funktioniert überhaupt nicht.
Leider blicke ich das mit den Pointern auch überhaupt nicht und ich finde es sehr unübersichtlich.
Mein Code:
Code: |
Sub TSNE_NewData(Byval V_TSNEID As Uinteger, Byref V_Data As String, Byval V_CallBackPtr As Client_Type Ptr)
MutexLock(G_ClientMux)
MessageFromClient=V_Data 'Dim Shared as String
ClientID=V_TSNEID 'Dim Shared as uInteger
MutexUnLock(G_ClientMux)
End Sub
Do Until InKey() = Chr(27) 'oder wie auch immer die schleife aussieht
'...
MutexLock(G_ClientMux)
If MessageFromClient<>"" Then
Verarbeite_Nachricht(ClientID, MessageFromClient)
MessageFromClient=""
End If
MutexUnLock(G_ClientMux)
'...
sleep 1, 1
Loop
|
funktioniert, aber ich bin mir nicht sicher, ob das nicht zu Chrases führen kann.
Muss in der Hauptschleife überhaupt ein MutexLock/Unlock sein? |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 24.12.2012, 16:32 Titel: |
|
|
1. Ja, muss String sein, ud nicht UInteger. Da hast du recht.
2. So wie du das geschrieben hast, kannst du das schon machen, is auch threadsafe, allerdings nicht nachrichtensicher.
Also, zur kurzen erklärung meines codes und deines codes.
Mein Source:
Ich lege eine Liste an. eine sogenante LinkedList. Das ist eine Liste, die man erweitern und verkleinern kan (ähnlich einem array), jedoch mit einigen geschwindigkeitsvorteilen. Mehr infos dazu goibts in den tutorials in freebasic-portal.de.
an diese liste hänge ich einen neuen eitrag an, sobald eine nachricht eintrudelt. dieser eintrag beinhaltet die nachricht selbst und die id, von der sie kam.
damit das ganze threadsafe ist utze ich ein mutex, das ich vor dem ändern der liste sperre, und nach dem ändern wieder entsperre.
in der hauptschleife wird geprüft, ob die liste einträge beinhaltet. wen dem so ist, wird der erste eintrag oin der liste heraus genommen und zwischegespeichert.
anschliessend dieser erste eintrag gelöscht, womit die nachfolgenden nach vorne rücken.
dieser zwischengespeicherte eintrag wird daraufhin der auswert-fuktion von dir übergeben.
dadurch verliehrst du keine einzige nachricht, da jede eingehende in diese liste aufgeommen wird.
zu deinem source:
du machst "ansich" etwas ähnliches. du speicherst die nachricht jedoch nicht in eine liste, nachricht für nachricht, sondern in eine einzige, einzelne variable. sprich, wenn der fall eintreten sollte, das 2 nachrichten hinteienander eingehen, bevor der hauptthread diese verarbeiten konnte, dan wird die erste von der zweiten (und der dritten, und vierten, usw.) überschrieben, bevor der hauptthread diese verarbeiten konnte.
deswegen nutzt mein source auch eine liste, an der die nachrichten angehängt werden, und nicht überschreibt.
bei dir ist es also möglich, das du nachrichten verliehrst. bei meinem source ist das nicht der fall.
wen du also doppelte ameldungen bekommst, kann da entweder daran liegen, das dieser eintrag doppelt in der liste vorhanden ist, du ihn eventuell 2x verarbeitest, oder der client ihn 2x sendet.
oder auch, das der server ihn 2x in die liste einträgt, da er vieleicht an alle und an sich selbst übermittelt wird.
warum, ist schwer zu verfolgen, wenn man nicht server udn client sourcecode zur verfügung hat.
Bezüglich Pointer:
Also ... wenn du Dim ABC as UInteger anwendest, dann erzeugt dir dein Programm einen speicherbereich der 4 byte gross ist.
indem du ABC verwendest .. z.B. abc = 1, sagst du dem programm, das er in diese variable (in den spoeicherbereich welcher abc repräsentiert) den wert 1 schreiben soll
du kennst jetzt allerdings nur einen willkürlichen namen dieser variable. wo genau im speicher dieser speicherplatz liegt, ist dir nicht bekannt.
das kann mit z.B. mit CPtr(abc) herausfinden.
diese fuktion gibt dir die adresse (den speicherplatz) zu dieser variable zurück.
diese adresse ist eindeutig, und definiert hier expliziet den speicherplatz für diese eine variable. jede variable hat prinzipiell eine eigene adresse.
damit das programm weis, wo es die daten im speicher ablegen muss, braucht eben jede variable eine adresse (speicheradresse)
mit dieser adresse kann man also auf den speicher zugreifen.
du kannst jetzt z.B. einen sogenanten zeiger (pointer) erzeugen.
dim abc_pointer as uinteger ptr
dies ist eine variable (geauso wie abc), die jedoch keine normalen zahloenwerte oder textzeichen speichert, sondern speicheradressen.
abc_pointer = cptr(abc)
jetzt hast du also die adresse von abc in eine pointer-variable (abc_pointer) gespeichert.
wenn du jetzt auf diesen speicher zugreifen willst, kannst du das mithilfe von * tun.
Print *abc_Pointer
hier wird dir das Print jetzt "1" ausgeben. Das Programm weis, das du keine variable sondern einen pointer hast, liest die speicheradresse aus, greift auf diese adresse zu und gibt dir den wert, welcher an dieser adresse liegt zurück.
der unterschied ist also, das du mit normalen variablen den wert der eigenen variable auslesen / manipulieren kanst, und mit pointer-variablen kannst du fremde (nicht die eigene) auslesen. Hierzu teilt man dieser natürlich erst die adresse der fremden speicheradresse mit.
das ist eigentlich auch schon das ganze prozedere dahinter.
was man damit jetzt alles anstellen kann, sollte erstmal ebensächlich sein. aber, als beispiel kann man so z.B. speicherbereiche über das gesammte programm hinweg übermitteln, ohne die daten zu kopieren. man reicht einfach den "pointer" weiter. dieser ist 4 byte gross. im gegensatz zu z.B. einem 1000Byte grossen Text-String, welcher bei jedem weiterreichen immer wieder kopiert werden muss.
Und solche Pointer verwende ich in der liste (Linked List). Es ist quasi eine liste aus speicheradressen, welche die daten speichert.
Steckt zwar noch n ticken mehr dahinter, aber das ist erstmal egal.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
stevie1401
Anmeldungsdatum: 04.07.2006 Beiträge: 133
|
Verfasst am: 24.12.2012, 16:38 Titel: |
|
|
Vielen Dank für deine ausführliche Erklärung.
Dein Code (String geändert), funktioniert dennoch nicht, wie oben schon erwähnt.
Man genau 1 Meldung senden, danach nimmt der Server keine weiteren Nachrichten auf.
Du kannst ja noch mal nachgucken, was da evtl nicht stimmen könnte.
Euch allen eine schöne Weihnacht  |
|
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.
|
|