Toon posts:

[C++>Win32>Threads] ik snap er niks meer van

Pagina: 1
Acties:
  • 162 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
[MFC]
Ik had dus voor een programmaatje een soort van progresswindow gemaakt ( "Now running <blaat>" ) met een cancelbutton. Deze progresswindow draait in een aparte thread. De threadfunctie is gedeclareerd als :
code:
1
static UINT CProgrammaClass::ProgressbarThread( LPVOID lpParam );

zodat ik toegang heb tot de interne member variabelen van de CProgrammaClass. Ondermeer zijn er deze variabelen:
code:
1
2
CString m_sProgresstext; // de tekst die er op de progressdialog moet komen
BOOL m_bHideProgress; // Zet op TRUE om de dialog af te sluiten, FALSE om hem te tonen

De Progressbarfunctie is ongeveer dit (ff snel in pseudocode):
code:
1
2
3
4
5
6
7
8
9
10
UINT CProgrammaClass::ProgressbarThread( LPVOID lpParam )
{
CProgrammaClass *pThis = (CProgrammaClass*) lpParam;
CreateAndShowProgressDialog();
while (!pThis->m_bHideProgress)
{
  Verwerk_window_messages();
}
DestroyProgressWindow()
}

Dit is allemaal volgens het Win32/MFC boekje.
Maar nu komt het !
Als ik bv in de functie CProgrammaClass::DoeIets() een thread begin met ProgressBarThread als functie en vervolgens m_sProgressText aanpas, dan doet ie dit mooi. de tekst in het venster verander. Als ik echter m_bHideProgress op TRUE zet, verbergt ie het venster niet. Het blijft gewoon heel lullig op het scherm staan.
Maarrrr
Als ik vlak daarna Sleep( 0 ); aanroep, verdwijnt dit wel :? :?
Dus deze code doet t niet:
code:
1
2
3
4
5
bool CProgrammaClass::WerktNiet() 
AfxBeginThread( ProgressbarThread, this );
// doe iets wat tijd kost
m_bHideProgress = TRUE;
return true;

terwijl dit perfect werkt
code:
1
2
3
4
5
6
bool CProgrammaClass::WerktNiet() 
AfxBeginThread( ProgressbarThread, this );
// doe iets wat tijd kost
m_bHideProgress = TRUE;
Sleep( 100 );
return true;

Ik zoek dus geen oplossing maar een verklaring hoe dit komt. Wie heeft een idee?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

ik kan zo snel even geen verklaring verzinnen, maar wat je wel moet doen is m_bHideProgress volatile maken

dus
code:
1
volatile BOOL m_bHideProgress;

dan weet de compiler dat ie de waarde dus altijd uit het geheugen moet halen. Anders krijg je de kans dat ie het 1 keer inlaadt in een register, en daarna dat register steeds controleert in de while lus, wat dus nooit zal veranderen. volatile is speciaal voor dit doel gemaakt, dus dat een variabele in principe op elk moment veranderd kan worden.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Hmm, kheb de variabele dus volatile gemaakt, en de Sleep weggehaald, maar hij doet t dan nog steeds niet.
Ik heb de Sleep teruggezet, en jawel, werkt weer...

Kan het niets te maken hebben met de manier waarop windows threads afhandeld, in plaats van een puur C++ probleem ivm classes?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

het was meer bedoeld als tip, niet als oplossing :)

maar ik heb verder echt werkelijk geen idee... Hoe lang duurt datgene wat je doet ongeveer?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Hangt ervanaf, het is een script interpreter, en de dialog toont "now running line x/y of script z", dus naargelang de lengte van het script.

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 14-09 17:42

Gerco

Professional Newbie

Ik heb wel vaker meegemaakt dat als een thread erg druk bezig is, dat de andere threads van je app of windows geen tijd meer hebben om het scherm bij te werken.

In dat geval helpt een sleep(0) wel, want dan geef je even control aan windows, die verwerkt alle wachtende window messages en je app's window kan weer redrawen.

Blijkbaar werkt de pre-emptieve multitasking niet altijd even goed :?

Er is hier vast een nette manier voor, maar die weet ik niet.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op dinsdag 09 oktober 2001 21:41 schreef SpHeaRe het volgende:
Ik zoek dus geen oplossing maar een verklaring hoe dit komt. Wie heeft een idee?
Ik zal ze allebei geven:

Verklaring: je verneukt compleet de windows message queue door de thread de lucht uit te knallen voor ie z'n message queue leeg heeft (met daarin de WM_CLOSE onder andere gok ik).

Oplossing: ga jij eens even heel snel het hoofdstuk over events overlezen in dat Win32 boekje zodat je dit wel strak synchroon oplost. En knoop sowieso de input processing van die 2 threads dmv. AttachThreadInput aan mekaar, anders hebben ze helemaal niets over elkaar's window te zeggen.

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 10 oktober 2001 01:51 schreef curry684 het volgende:

Verklaring: je verneukt compleet de windows message queue door de thread de lucht uit te knallen voor ie z'n message queue leeg heeft (met daarin de WM_CLOSE onder andere gok ik).
daar zat ik eerst ook aan te denken, maar aangezien hij DestroyWindow aanroept leek het mij niet uit te maken... of wordt de window ook echt daadwerkelijk pas gedestroyed als de window een WM_DESTROY tegenkomt in z'n windowproc? Da's iig niet echt duidelijk uit de MSDN te halen

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op woensdag 10 oktober 2001 02:02 schreef OiSyN het volgende:
daar zat ik eerst ook aan te denken, maar aangezien hij DestroyWindow aanroept leek het mij niet uit te maken... of wordt de window ook echt daadwerkelijk pas gedestroyed als de window een WM_DESTROY tegenkomt in z'n windowproc? Da's iig niet echt duidelijk uit de MSDN te halen
Ik ken MFC niet fantastisch, maar MSDN meldt over de WM_CLOSE message dat de DefWindowProc erop respondeert met DestroyWindow. En daar MFC een SUPERFLINTERDUNNE schil om Win32 is ga ik ervan uit dat die erop rekent dat dat gebeurt. WM_DESTROY volgt sowieso pas na de call naar DestroyWindow, en volgens de docs again: This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed. During the processing of the message, it can be assumed that all child windows still exist.

Ennuh, hij roept DestroyProgressWindow aan, dat is niet hetzelfde als de DestroyWindow API-call :7

Professionele website nodig?


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 23:59
Op woensdag 10 oktober 2001 01:51 schreef curry684 het volgende:

[..]
En knoop sowieso de input processing van die 2 threads dmv. AttachThreadInput aan mekaar
Deze meneer schrijft niet hoe hij dat progress geval destroyed in DestroyProgressWindow(..).

Als hij dat doet door een WM_DESTROY te sturen naar dat window is er toch helemaal niets aan de hand? In dat geval hoef je dus ook niet de input processing aan elkaar te knopen.

Of heeft dat progress geval geen eigen messageque gekregen?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Op woensdag 10 oktober 2001 01:51 schreef curry684 het volgende:

[..]

Ik zal ze allebei geven:

Verklaring: je verneukt compleet de windows message queue door de thread de lucht uit te knallen voor ie z'n message queue leeg heeft (met daarin de WM_CLOSE onder andere gok ik).
Onzin, elk process heeft zn eigen message queue. Als je een process stopt op een of andere manier, wordt de messagequeue van dat process verwijderd. Boeie dat daar dan nog 100 messages in staan.
Oplossing: ga jij eens even heel snel het hoofdstuk over events overlezen in dat Win32 boekje zodat je dit wel strak synchroon oplost. En knoop sowieso de input processing van die 2 threads dmv. AttachThreadInput aan mekaar, anders hebben ze helemaal niets over elkaar's window te zeggen.
Ook flauwekul, threading in win32 is op win9x anders dan op NT based kernels. Win9x kernels hebben een threadscheduler die zo is getuned dat foregroundthreads dermate vaak de CPU krijgen dat starvation op kan treden als je daar veel messages naartoe stuurt. Op NT based kernels heb je daar geen last van.

Verder heb je windows en je hebt threads. Je kunt best 2 windows hebben en 10 threads die naar die windows schrijven, of 2 windows en 1 thread. Ze hoeven niet over elkaars window iets te vertellen te hebben, het gaat er puur om dat de messagepumps van beide windows (of zo je wilt, van het process waar de windows van zijn) de messages afhandelen terwijl de workerthread(s) doorgaan. Het is vaak makkelijk om per window een thread te starten om de messagepump af te handelen van dat window, maar lang altijd hoeft dat niet.

Verwijderd

Op dinsdag 09 oktober 2001 21:41 schreef SpHeaRe het volgende:
[...]
Ik zoek dus geen oplossing maar een verklaring hoe dit komt. Wie heeft een idee?
Met 1 processor/win9x systemen heb je het fenomeen dat 1 thread de andere 'doodknijpt', zg 'thread starvation'. De sleep(100) zorgt ervoor dat die thread sowieso even geen cpu tijd krijgt en dus dat de andere thread zn werk kan doen. Multitasking is wel pre-emptive op win9x, maar niet zo vrijblijvend als op NT based kernels.

Curry zegt al een goed ding: kijk naar events. Jij pakt multithreading compleet verkeerd aan. Wat win32 zo gemakkelijk maakt voor multithreading is het eventsystem: elke thread geef je een messagepump (een loop die kijkt of een message is gearriveerd en die dan afhandelt) zodat je vanuit threads messages naar andere threads kunt sturen en dus het gedrag van threads kunt bepalen, 'sturen', op een asynchrone, nette manier. Jij implementeert in feite busy waiting, door een variabele te gaan pollen. Beter is een handler te maken voor een WM_MYMESSAGE_QUIT message te definieren (WM_USER+1 bv) en daar een handler voor te definieren in je thread en een andere thread die te sturen.

In jouw geval heb je een windowtje wat niets doet, anders dan wachten op de gegevens die hij moet weergeven. Het is dan dus verstandig om het windowtje met je progressinfo in een aparte thread te openen, de messagepump draait dan in een aparte thread, en de messagepump te laten reageren op een message, bv WM_MYMESSAGE_DISPLAYINFO (ook zelf gedefinieerd). De messagepump van je progressinfo doet verder niets, die staat in de messagepump te wachten op een message, wat geen cpu tijd kost (mfc regelt dat voor je) en zodra jij een message stuurt van 'hey, display info', wordt hij wakker, leest de info die hij moet weergeven (die je bv opslaat in een shared variabele tussen threads (afschermen met critical sections!), en zet die info in zijn windowtje, en gaat weer pitten in zn messagepump. Druk je op cancel, dan komt er een WM_COMMAND message aan in zn messagepump, je handelt die af in je progresswindow message handler voor WM_COMMAND, echter op dat moment stuur je ook een message naar de main thread, die het progreswindowtje heeft gecreeerd, dat er gecanceled moet worden. Je sluit gewoon je windowtje af op de gebruikelijke manier en verder niets. De messagepump van je main thread ontvangt die cancel message en moet dan zorgen dat de workerthread die gestopt moet worden, wordt gestopt op een nette manier. Threads stoppen is een narigheid, vooral als ze een lange loop doorlopen die enige tijd kost. Echter, het is zaak je workerthread's werk op te delen in kleinere stukjes zodat de thread ook kan blijven reageren op messages van buitenaf, immers je wilt dat hij stopt zodra hij bericht krijgt van buitenaf.

Dit klinkt wellicht allemaal wat complex. Dat is het ook. Veel mensen denken dat multithreading simpel is, maar te vaak storten de multithreaded applicaties van die mensen hopeloos ter aarde wanneer de situaties iets anders zijn dan hun eigen ontwikkelsystemen (bv 2 cpu's ipv 1 etc). Multithreading is ook vaak niet nodig, in jouw geval kun je wanneer je de progressinformatie wilt updaten, dat ook middels een call vanuit je workerloop doen, ipv dat je een message stuurt naar de thread die de progressinfo op het scherm plaatst. ALs het al zo in VB kan, kun je dat zeker in MFC/C++ :D

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op woensdag 10 oktober 2001 09:12 schreef farlane het volgende:
Deze meneer schrijft niet hoe hij dat progress geval destroyed in DestroyProgressWindow(..).
Inderdaad, en ik denk dat dat de clue is.
Als hij dat doet door een WM_DESTROY te sturen naar dat window is er toch helemaal niets aan de hand? In dat geval hoef je dus ook niet de input processing aan elkaar te knopen.
Tja ik gok uit de weinige informatie ook alleen maar wat ie exact fout doet (leuk die pseudocode maar er staat weinig nuttigs in). En roep dus maar een paar dingen die theoretisch zouden kunnen helpen, zonder dat ik de volledige code hiervan zie kan ik moeilijk beroordelen wat er fout gaat...

Ik ben sowieso niet gecharmeerd van windows in meerdere threads omdat je er veels te veel troep tussen heen en weer moet rammen in de message processing. Dan liever een GUI-thread en x manager- of workerthreads.
Of heeft dat progress geval geen eigen messageque gekregen?
Iedere thread krijgt een message queue toegewezen op het moment dat ie een GDI- of USER-functie gebruikt.

Professionele website nodig?


Verwijderd

Topicstarter
Wat me is opgevallen is dat iedereen maar zit door te drammen over de messageloop van de progressdialog, maar dat is het probleem dus niet. Het probleem is dat de variabele m_bHideProgress niet wordt geüpdate als ik Sleep(0) niet aanroep, terwijl andere variabelen dit wel doen.
Mijn messageloop is in orde.

Verwijderd

Dat komt door de thread starvation en je compleet verkeerde aanpak van multithreading. Je vroeg waar het aan lag. Dat antwoord heb je gekregen. Nu moet je niet emmeren dat dat antwoord je niet bevalt, dat is helaas inherent aan je aanpak :D

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 23:59
- Je threadfunctie ziet wel dat ie false wordt? -> Kijk naar je DestroyWindowFunctie() en de messageloop van je ProgressWindow

- Je threadfunctie ziet niet dat ie false wordt? -> Euhhhmm...

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 10 oktober 2001 02:34 schreef curry684 het volgende:

[..]

Ik ken MFC niet fantastisch, maar bla bla bla bla
ik had het niet over MFC, maar puur over de win32 api :)
Ennuh, hij roept DestroyProgressWindow aan, dat is niet hetzelfde als de DestroyWindow API-call :7
ja, DUH!, maar ik ga er van uit dat ie in zijn functie DestroyProgressWindow ergens DestroyWindow aanroept (hoe wilt ie m anders sluiten) :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Bart Coppens
  • Registratie: April 2000
  • Laatst online: 25-11-2021
[ik probeer te helpen, maar ik ben niet echt een held met threads en C++]
Toen ik vroeger wel eens zoiets deed in Delphi (weliswaar zonder een parte thread voor die progressbar), had ik een soortgelijk probleem. Het _leek_ of de teller niet werd geupdated, maar ik kon dit altijd verhelpen door de counter opnieuw te laten 'tekenen' door blaat.refresh. Ik veronderstel dus dat (zoals eerder gezegd) het scherm niet wordt geupdated doordat er te druk wordt gewerkt aan andere dingen. Ik veronderstel dat er wel een functie zal zijn die hetzelfde doet bij C++/Win32?
(ik hoop dat ik niet al te veel onzin verkocht heb in deze thread van nogal hoog niveau)
[/leek-mode]

Copyright Auteur heeft Tweakers.net BV geen exclusieve licentie op bovenstaande post verleend. Voorafgaande en uitdrukkelijke schriftelijke toestemming van Tweakers.net BV is dus niet noodzakelijk voor het vermenigvuldigen van bovenstaande post


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Otis: niet elke thread heeft een message pump, dat is volledig aan de user om die te implementeren in een thread. Wat elke thread wel heeft is een message queue :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • The End
  • Registratie: Maart 2000
  • Nu online

The End

!Beginning

Volgens mij is de oplossing zo simpal als Bart zegt... Als je de redraw functie van het window of de progressbar aanroept heb je grote kans dat ie het wel doet....

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op woensdag 10 oktober 2001 10:06 schreef Otis het volgende:
Onzin, elk process heeft zn eigen message queue.
Elke thread zelfs zodra ie blahdiblah (zie vorige post).
Als je een process stopt op een of andere manier, wordt de messagequeue van dat process verwijderd. Boeie dat daar dan nog 100 messages in staan.
Thread, niet process. :)

En dat je 100 messages eventjes truncate waar het systeem al of niet een bevestigend antwoord op verwacht (of in het geval van WM_CLOSE die default DestroyWindow triggert...) kun je best vreemd gedrag krijgen. Zoals het niet afsluiten van een window gok ik.
Ook flauwekul, threading in win32 is op win9x anders dan op NT based kernels. Win9x kernels hebben een threadscheduler die zo is getuned dat foregroundthreads dermate vaak de CPU krijgen dat starvation op kan treden als je daar veel messages naartoe stuurt. Op NT based kernels heb je daar geen last van.
Klopt 100%, hij zegt echter nergens dat ie Win9x gebruikt, en ik ging er niet van uit dat iemand suicidaal genoeg zou zijn om Visual Studio op een 9x systeem te draaien. :)

Als dat wel zo is heb je natuurlijk 100% gelijk, maar mijn opmerking blijft ook correct dan: namelijk dat ie het verneukt door de message queue weg te mieteren voordat deze helemaal verwerkt is. Of dat nu komt doordat de thread starved is of doordat ie binnen 5ms gekilled wordt is van secundair belang.

Oftewel je maakt een mooi event object dat je triggert in antwoord op de WM_DESTROY, en de eerste thread laat je niet met die volatile bool werken maar met QueueUserAPC in de correcte thread context een WM_CLOSE naar het progresswindow sturen, waarna ie met WaitForSingleObject op dat event gaat wachten voordat ie verder gaat. Ongeveer ;) Zolang je maar onthoudt dat je hier een 'twee-traps raket' hebt: eerst moet je het sluiten van het window triggeren, en daarna moet het correct afsluiten van het window het sluiten van de thread triggeren. Dus niet zoals je nu doet in een ruk door.

ps. inderdaad ik was vannacht om 3 uur niet meer zo helder :Z :Z :Z :Y)

Professionele website nodig?


  • The End
  • Registratie: Maart 2000
  • Nu online

The End

!Beginning

Op woensdag 10 oktober 2001 13:37 schreef OiSyN het volgende:
Otis: niet elke thread heeft een message pump, dat is volledig aan de user om die te implementeren in een thread. Wat elke thread wel heeft is een message queue :)
Dit is ook niet waar... Alleen MFC threads hebben een messagequeue en/of messagepump (messagepump is wel standaard bij MFC trouwens...)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op woensdag 10 oktober 2001 12:41 schreef SpHeaRe het volgende:
Wat me is opgevallen is dat iedereen maar zit door te drammen over de messageloop van de progressdialog, maar dat is het probleem dus niet. Het probleem is dat de variabele m_bHideProgress niet wordt geüpdate als ik Sleep(0) niet aanroep, terwijl andere variabelen dit wel doen.
Mijn messageloop is in orde.
In je originele post zei je:
Als ik echter m_bHideProgress op TRUE zet, verbergt ie het venster niet.
Dus nu zit je jezelf nogal tegen te spreken, omdat inderdaad iedereen het antwoord op die originele kwestie gaf. |:(

Zoals je het nu stelt: luister naar Otis, het is thread starvation als je op een Win9x-systeem zit.

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 10 oktober 2001 13:53 schreef The End het volgende:

[..]

Dit is ook niet waar... Alleen MFC threads hebben een messagequeue en/of messagepump (messagepump is wel standaard bij MFC trouwens...)
MFC is hier niet aan de orde, dus laat dat er alsjeblieft buiten :)

als je een threads start heeft ie idd nog geen messagequeue, maar zodra je een GUI of USER functie aanroept wordt er een aangemaakt. Mijn vorige uitspraak klopte dus idd niet helemaal, je zult het maar bij deze moeten houden. Wat ik zei over de messagepump klopte wel, en daar ging het ook om :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Op woensdag 10 oktober 2001 13:37 schreef OiSyN het volgende:
Otis: niet elke thread heeft een message pump, dat is volledig aan de user om die te implementeren in een thread. Wat elke thread wel heeft is een message queue :)
Zeg ik ook niet :) -> "... elke thread geef je een messagepump ...". Die geef je dus :P

Op zich is messages doorgeven mbt PostThreadMessage() een van de manieren om synchronisation te doen, iets wat de OP wilde. MFC heeft een serie objects, afgeleid van CSyncObject om synchronisation in goede banen te leiden, tussen CThread objects. Wellicht dat de OP daar eens naar moet gaan kijken.

Ik gokte op een win9x systeem gezien de symptomen die de OP beschreef en die sterk overeen kwamen met mijn eigen ervaringen toen ik mn multithreaded DemoGL runde op een win9x doos, waarbij de renderthread voor de OpenGL console de workerthread die alles laadde volledige wurgde, terwijl onder NT4 alles als een zonnetje werkte (op dezelfde bak). :D.

Verwijderd

Op woensdag 10 oktober 2001 14:22 schreef OiSyN het volgende:

[..]

MFC is hier niet aan de orde, dus laat dat er alsjeblieft buiten :)
errr... check het eerste woordje in z'n posting :D
als je een threads start heeft ie idd nog geen messagequeue, maar zodra je een GUI of USER functie aanroept wordt er een aangemaakt.
Klopt idd. ik lees het net in 'Queued messages' in de PlatformSDK (Platform SDK Documentation/User Interface Services/Windows User Interface/Windowing/Messages and Message Queues/About Messages and Message Queues/Message Routing)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op woensdag 10 oktober 2001 14:43 schreef Otis het volgende:

[..]

errr... check het eerste woordje in z'n posting :D
woepsie, even niet gezien, i stand corrected :D

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op woensdag 10 oktober 2001 14:43 schreef Otis het volgende:
Klopt idd. ik lees het net in 'Queued messages' in de PlatformSDK (Platform SDK Documentation/User Interface Services/Windows User Interface/Windowing/Messages and Message Queues/About Messages and Message Queues/Message Routing)
Zei ik een stuk hierboven ook al :7

Je krijgt ook een queue kado bij GDI-functies. En het staat ook in de help van AttachThreadInput :)

Professionele website nodig?


Verwijderd

Topicstarter
Op woensdag 10 oktober 2001 13:46 schreef The End het volgende:
Volgens mij is de oplossing zo simpal als Bart zegt... Als je de redraw functie van het window of de progressbar aanroept heb je grote kans dat ie het wel doet....
uhm, de progresswindow wordt zonder problemen hertekend, dat is overigens niet het probleem. Het probleem is: Indien ik een waarde toeken aan de variablele m_bHideProgress wordt die nieuwe waarde NIET doorgegeven aan de thread. Als ik een nieuwe waarde toeken aan EENDER welke andere variabele, wordt dit WEL herkend in de thread.
Als ik daarna Sleep(0) aanroep; wordt de variabele WEL geupdate.

Dat is dus het probleem, en nogmaals, het progressvenster heeft er niets mee te maken, het gaat over die variabele!
(sorry als dit niet zo duidelijk was in mijn vorige post(s))

edit:
Overigens draai ik (enkel) windows 2000; geen 98

Verwijderd

Topicstarter
Nu ik mijn eerste post herlees, heb ik het inderdaad compleet verkeerd geformuleerd |:(
Sorry hiervoor. Het eigenlijke probleem staat dus in mijn vorige post hierboven

  • Abidan
  • Registratie: Februari 2001
  • Laatst online: 16-09 17:42
[quote]Op dinsdag 09 oktober 2001 22:19 schreef Gerco het volgende:
Ik heb wel vaker meegemaakt dat als een thread erg druk bezig is, dat de andere threads van je app of windows geen tijd meer hebben om het scherm bij te werken. [...]

Heb je wel gedacht aan de priority van je thread??? Je kunt je thread een prioriteit meegeven. De belangrijkste gaan dan eerst, en dan de minder belangrijke. Als deze taak een (te) hoge prioriteit heeft, kan dat de verklaring zijn voor het niet-verversen van het scherm.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 17-09 22:25

Janoz

Moderator Devschuur®

!litemod

Volgens mij heeft het probleem dat jij nu hebt meer te maken met het feit dat je hoofd programma geen thread is. Ikzelf werk eigenlijk alleen met threads in java, dus ik kan er flink naast zitten, maar aan de andere kant.. Het zal vast wel flink overeenkomen..

Je probleem is meer dat je hoofdprogramma aan 1 stuk doorgaat. Hierdoor krijgt je thread geen processor tijd om uberhaupt iets met de nieuwe bool te doen. Vandaar ook dat het met de sleep ertussen wel werkt. Op die manier geef je in je hoofd programma iets aan als "OK, ik ga ff slapen zodat andere threads ff een beurt krijgen". De variable wordt dus wel degelijk veranderd, maar de thread krijgt geen processor tijd om er iets mee te doen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op woensdag 10 oktober 2001 21:05 schreef SpHeaRe het volgende:
Indien ik een waarde toeken aan de variablele m_bHideProgress wordt die nieuwe waarde NIET doorgegeven aan de thread. Als ik een nieuwe waarde toeken aan EENDER welke andere variabele, wordt dit WEL herkend in de thread.
Als ik daarna Sleep(0) aanroep; wordt de variabele WEL geupdate.
Maak die bHideProgress eens heel snel volatile dan. Als je je afvraagt wat dat doet, lees de docs even door:
The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread.

The following example declares a volatile integer nVint whose value can be modified by external processes:
code:
1
int volatile nVint;

Objects declared as volatile are not used in optimizations because their value can change at any time. The system always reads the current value of a volatile object at the point it is requested, even if the previous instruction asked for a value from the same object. Also, the value of the object is written immediately on assignment.

One use of the volatile qualifier is to provide access to memory locations used by asynchronous processes such as interrupt handlers.

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op woensdag 10 oktober 2001 22:20 schreef Janoz het volgende:
Volgens mij heeft het probleem dat jij nu hebt meer te maken met het feit dat je hoofd programma geen thread is. Ikzelf werk eigenlijk alleen met threads in java, dus ik kan er flink naast zitten, [...knip...]
Inderdaad :Y)

Tuurlijk is het hoofdprogramma een thread (main process thread om precies te zijn). Knap dat ie iets uitvoert als dat niet zo zou zijn... :?

Professionele website nodig?


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
curry684: Inderdaad :Y) , Tuurlijk is het hoofdprogramma een thread
Wat in Java trouwens ook zo is ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Op woensdag 10 oktober 2001 23:59 schreef curry684 het volgende:
Maak die bHideProgress eens heel snel volatile dan. Als je je afvraagt wat dat doet, lees de docs even door:
Ehh curry 2e en 3e posts in deze draad niet gelezen? heb je je dag niet? nix voor jou om er een beetje achter aan te kachelen.. :*

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op donderdag 11 oktober 2001 00:17 schreef Yarvieh het volgende:

[..]

Ehh curry 2e en 3e posts in deze draad niet gelezen? heb je je dag niet? nix voor jou om er een beetje achter aan te kachelen.. :*
dat komt, hij heeft de laatste tijd nogal last van nachtmerries enzo... over vreemde exceptions die gethrowed worden en dat soort ongein, daar kan hij ook niets aan doen :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

benchmark ontwennings verschijnselen?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op donderdag 11 oktober 2001 00:17 schreef Yarvieh het volgende:
Ehh curry 2e en 3e posts in deze draad niet gelezen? heb je je dag niet? nix voor jou om er een beetje achter aan te kachelen.. :*
Die waren het correcte antwoord op het verkeerde probleem :D

Ik hielp Spheare er enkel even aan herinneren dat nu iedereen (incluis hijzelf...) feitelijk ook weet wat het echte probleem is dat nog steeds een mogelijke oplossing is :Y)

Ennuh:
dat komt, hij heeft de laatste tijd nogal last van nachtmerries enzo... over vreemde exceptions die gethrowed worden en dat soort ongein, daar kan hij ook niets aan doen
Niet natrappen he :(

:P

Professionele website nodig?


Verwijderd

Topicstarter
Op donderdag 11 oktober 2001 01:25 schreef curry684 een mogelijke oplossing
Helaas werkt dit niet; ik heb de desbetreffende variabele volatile gemaakt, en hij doet t nog steeds niet zonder de Sleep(0) :(

Verwijderd

Kan je niet een klein proof of concept ding in elkaar draaien zodat wij ook even kunnen stoeien er mee?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op donderdag 11 oktober 2001 17:36 schreef Yarvieh het volgende:
Kan je niet een klein proof of concept ding in elkaar draaien zodat wij ook even kunnen stoeien er mee?
En er dan meteen even definitief bij duidelijk maken of je op een Win98 of NT kernel draait?

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

hij draait win2k, dat heeft ie allang gezegd, wel blijven opletten he :)
Op woensdag 10 oktober 2001 21:05 schreef SpHeaRe het volgende:

[..]

edit:
Overigens draai ik (enkel) windows 2000; geen 98

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op donderdag 11 oktober 2001 19:15 schreef OiSyN het volgende:
hij draait win2k, dat heeft ie allang gezegd, wel blijven opletten he :)
[..]
Oeps had die edit gemist :)

Ben ondertussen wel benieuwd naar die proof-of-concept, volgens mij heeft ie iedere suggestie van ons al naar de prullenbak verwezen... :?

Professionele website nodig?


Verwijderd

Tja, maar wiens probleem is dat :D

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 08:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op vrijdag 12 oktober 2001 09:34 schreef Otis het volgende:
Tja, maar wiens probleem is dat :D
good point >:)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
de code is ongeveer dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
CScriptEngine::RunScript( CString strScriptname )
{
  // allerlei initialisaties
  // progressdialog tonen
    // (* Toon een progressdialog *)
    m_bShowProgressDialog = FALSE; 
    m_bProgressDialogCanceled = FALSE;
    AfxBeginThread( ProgressDialogFunc, this );
    m_sProgressDialogText = "Running script; please wait";

  // Script runnen
while ( pScript->GetNextLine( &sCurrLine )  && !m_bProgressDialogCanceled )
{
     m_sProgressDialogText.Format( "Evaluating line %d of %d in script %s\n(%s)", nLineCount, pScript->GetLineCount(), sScriptName, sCurrLine );
      // Evalueer de huidige regel in het script
}
Sleep(0);  // <--- dit is dus de bewuste sleep(0), zonder dit werkt t niet
m_bShowProgressDialog = FALSE; 
m_bProgressDialogCanceled = FALSE;
}


UINT CScriptEngine::ProgressDialogFunc(LPVOID lpParam)
{
    CScriptEngine*  pObjEngine = (CScriptEngine*)lpParam;

    CProgressDlg    dlgProgress;
    CString     strPrevText;

    dlgProgress.Show( NULL, true, true ); // Functie die Create Aanroept, parameters: hWndOwer (HWND); bDisableOwner(BOOL); bHideOwner(BOOL)
    dlgProgress.SetValue( -1 ); // Zorgt ervoor dat de statusbalk op 'onbepaald' gaat staan (= kleine animatie ipv progress)

    pObjEngine->m_bProgressDialogCanceled = FALSE;
    pObjEngine->m_bShowProgressDialog = TRUE;


    while ( pObjEngine->m_bShowProgressDialog ) // Dit is dus de variablele die NIET wordt geupdate zonder de Sleep(0)
    {

        if ( strPrevText.Compare( pObjEngine->m_sProgressDialogText ) != 0 )
        {
            dlgProgress.SetText( pObjEngine->m_sProgressDialogText );
            strPrevText = pObjEngine->m_sProgressDialogText ;
        }

        dlgProgress.DoEvents(); // Verwerk de wachtende messages
        pObjEngine->m_bProgressDialogCanceled = dlgProgress.m_canceled ; //Update de variablele
    }
    dlgProgress.Hide(); // Roept DestroyWindow aan, na alle tijdelijke objecten (DC's etc.) te hebben gedelete
    return 0;
}

class CScriptEngine
{
// andere zooi
// ...
protected:
      // ...
    // (* ProgressDialog *)
    static   UINT    ProgressDialogFunc( LPVOID lpParam );
           BOOL    m_bProgressDialogCanceled;
           CString m_sProgressDialogText;
    volatile   BOOL    m_bShowProgressDialog;
           HWND    m_hwndProgressDialogOwner;
}

void CProgressDlg::DoEvents()
{
    ASSERT(m_hWnd!=NULL);
    MSG msg;
    // Verwerk de dialog messages
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
    if(!IsDialogMessage(&msg))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);  
    }
    }
}

Verwijderd

Spheare, luistert: wat jij moet doen is wat documentatie lezen over synchronization. MFC heeft daar objects voor. (CSyncObject en derivatives). Er zijn een aantal manieren om synchronization te regelen tussen threads, dus dat de ene thread iets doet wat de ander hem opdraagt. Tik in in de search bij je MSDN: 'thread synchronization'. Een aantal dingen zijn hier al de revue gepasseerd, die nog eens herkauwen helpt niet.

[rant mode]
Je kunt nu weer gaan piepen dat je een ander probleem hebt. Dat heb je niet. Je hebt 2 threads die in hun tight loops rondgillen en in die loops met dezelfde variabele lopen te piemelen. Dijkstra wist al dat dat niet goed kon gaan. :). Lees nu die docs over synchronization van threads en je zult snappen wat we bedoelen en ook weten hoe je het op moet lossen.
[/rant mode]

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op vrijdag 12 oktober 2001 13:15 schreef Otis het volgende:
Je hebt 2 threads die in hun tight loops rondgillen en in die loops met dezelfde variabele lopen te piemelen. Dijkstra wist al dat dat niet goed kon gaan. :)
Otis de Dinerende Filosoof

:)

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op vrijdag 12 oktober 2001 13:15 schreef Otis het volgende:
Je kunt nu weer gaan piepen dat je een ander probleem hebt.
Ik heb het volgende probleem al gezien: die cancel gaat ook niet werken :)

Professionele website nodig?


Verwijderd

Topicstarter
Otis: kee, zal ik doen. :)
Curry: Cancel werkt toch wel hoor.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 04-09 14:38

curry684

left part of the evil twins

Op vrijdag 12 oktober 2001 16:27 schreef SpHeaRe het volgende:
Otis: kee, zal ik doen. :)
Curry: Cancel werkt toch wel hoor.
Mmmm okee die variabele gaat de andere kant op... net zo willekeurig overigens dat ie wel werkt denk ik :)

Hoe staat ie met je events en mutexes, al een stukje verder op pad?

Professionele website nodig?


Verwijderd

Topicstarter
Op vrijdag 12 oktober 2001 16:56 schreef curry684 het volgende:
Hoe staat ie met je events en mutexes, al een stukje verder op pad?
Mutexes heb ik al een stukje onder de knie, events ben ik nog druk mee aan het experimenteren, maar het zal wel lukken, denk ik :)
Pagina: 1