Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

1

27.07.2009, 23:23

Threadsicherheit und SendMessage()

Hallo,
ich beschäftige mich zurzeit mit WinHTTP (ob das etwas taugt muss ich noch herausfinden) im asynchronen Modus, das heißt, es werden mehrere HTTP-Requests "gleichzeitig" gestellt. Intern läuft das Ganze wohl über Threads ab, damit die Anwendung nicht blockiert, während auf Daten gewartet wird.

Nun möchte ich die empfangenen HTML-Quelltexte der einzelnen Anfragen in eine Textbox hintereinander einfügen. Die Hilftsfunktion sieht dazu wie folgt aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
void editCtrlAppend(HWND hEdit, LPCTSTR szText)
{
    int length = GetWindowTextLength(hEdit);

    SetFocus(hEdit);
    SendMessage(hEdit, EM_SETSEL, (WPARAM) length, (LPARAM) length);
    SendMessage(hEdit, EM_REPLACESEL, 0, (LPARAM) szText);
}


Mein Problem ist, das die empfangenen Antworten nicht beide hintereinander angezeigt werden, sondern immer nur die zuletzt empfangene. Die obige Funktion wird natürlich von mehreren Stellen aufgerufen und durch einige "billige" Abfragen habe ich herausgefunden, dass GetWindowTextLength(hEdit) bei jedem dieser Aufrufe 0 liefert, obwohl sich ja (außer beim ersten Mal) bereits Text in der Textbox befinden müsste. Und dass somit nichts hinten angefügt wird, ist auch klar.

Meine Frage ist nun, wie ich das verhindern kann. Um den Aufruf der obigen Funktion herum habe ich bereits mein Glück mit EnterCriticalSection/LeaveCriticalSection versucht, doch das änderte nichts an dem Verhalten.

Ich bin mir sicher, dass hier viele Leute wesentlich mehr Ahnung von Threads haben und vielleicht sofort das Problem erkennen.

Gruß
ph4nt0m
;)

ChrisJ

Alter Hase

Beiträge: 487

Wohnort: Schweich

Beruf: Schüler

  • Private Nachricht senden

2

28.07.2009, 10:27

hmm... ich kenne mich nicht wirklich damit aus, aber wenn du blockierende sockets in eigenen threads haben willst, benutzt du wohl mit sicherheit WSAAsyncSelect(...). der function kannst du als parameter WM_SOCKET_NOTIFY übergeben. dann bekommst du jedes mal eine nachricht vom typ WM_SOCKET_NOTIFY, wenn du was lesen kannst.
"Don't trust your eyes: They are a hell of a lot smarter than you are"

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

3

28.07.2009, 11:17

Genau, so ähnlich ich es bei WinHTTP auch. Dem Aufruf von WinHttpOpen() übergebe ich das Flag WINHTTP_FLAG_ASYNC und vor dem Senden der eigentlichen Anfrage lege ich mit WinHttpSetStatusCallback() eine Callback-Funktion fest, die dann immer aufgerufen wird, sobald irgendein Ereignis eintritt (z.B. dass Daten zum Lesen bereit sind).

Und sobald ich sicher bin, dass alles übertragen wurde, füge ich diese empfangenen Daten (Quelltext der Seite) in eine Textbox ein (dazu dient die obige Funktion im ersten Post). Das Problem ist eben, dass mehrere Requests laufen (zur Zeit zwei) und somit auch mehrfach eben diese Funktion aufgerufen wird. Da das anscheinend fast zeitgleich geschiegt, wirkt es für mich so, als wenn nach dem Aufruf von SendMessage intern noch nicht sofort alles erledigt wird (obwohl das ja im Gegensatz zu PostMessage bei SendMessage gerade der Fall sein sollte), sodass der zweite Aufruf immer noch eine leere Textbox vorfindet, obwohl ja bereits einmal etwas hinzugefügt wurde.
;)

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

4

28.07.2009, 14:12

schon mal versucht, das ganze mit einer CRITICAL_SECTION zu schützen?
scheint so, als ob der thread bei der berechnung der länge unterbrochen
wird. ergo sehen beide nur ide länge 0
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

5

28.07.2009, 14:27

Wie bereits erwähnt habe ich den Aufruf meiner Funktion mit EnterCriticalSection/LeaveCriticalSection umschlossen, was allerdings nichts geändert hat.
;)

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

6

28.07.2009, 16:04

sry nicht gesehen :(

doku SendMessage:

Zitat von »"MSDN"«


If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure.


vielleicht passiert da folgendes:

thread1 -> enter
thread2 -> muss warten
thread1 -> SendMessage
--context-switch--
thread2 -> will die funktion callen -> muss aber warten

das du eine deadlock situation hast.

versuchs mal mit logging (und die logging-class mit einer anderen C_S
schützen).
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

7

28.07.2009, 16:40

Naja, müsste nicht bei einem Deadlock das gesamte Programm irgendwie stehen bleiben, wenn die Threads jeweils auf den anderen warten? Das Programm funktioniert nämlich soweit ohne Probleme, es fehlt eben nur der zweite Quellcode in der Textbox.
;)

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

8

28.07.2009, 17:41

nein :D nur der zweite thread müsste warten. das ist ja das miese
bei multithreading
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

ph4nt0m

Frischling

  • »ph4nt0m« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student

  • Private Nachricht senden

9

28.07.2009, 18:01

Hmm, wenn nur ein Thread im Hintergrund blockiert wird, würde ich davon natürlich wenig merken. Allerdings habe ich nach der CriticalSection, innerhalb welcher editCtrlAppend() aufgerufen wird, mal einen einfachen Beep-Befehl eingefügt und ich höre auf jeden Fall zweimal den Piepton. Müsste nicht nach deiner "Theorie" einer der beiden Threads in bzw. vor der Section hängen bleiben und somit gar nicht zur Ausführung der Beep-Funktion kommen? :?
;)

Werbeanzeige