[C++] GUI bevriest bij COM port acties

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Black-Xjuh
  • Registratie: Oktober 2002
  • Laatst online: 14-04 10:23
Ik heb een probleem in Borland C++ Builder met de user interface die blijft hangen.

In grote lijnen even uitgelegd heb ik een form met een status label.

Deze staat eerst op "wachten" bijvoorbeeld.

Als ik dan een functie aanroep om connectie te maken met de COM port die er ongeveer zo uitziet:

code:
1
2
3
4
5
6
7
void connectComPort (void) {
    Form->Status->Caption = "verbinding maken";

    // stuk om te connecten met de COM port

    Form->Status->Caption = "verbonden";
}


Dan gaat het dus mis met de status, als die geconnect is met de COM port veranderd de status in "verbonden" maar "verbinding maken" komt nooit in beeld.

Hij hangt dus een soort van bij het connecten met de COM port, nu kan ik daar wel in komen maar voordat de COM port wordt aangesproken zou ik de status al willen veranderen.

Wat is hier een oplossing voor of wat doe ik fout?

Acties:
  • 0 Henk 'm!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
De GUI wordt pas aangepast nadat je methode is afgehandeld. Een snelle oplossing is om de update te forceren met: (plaatsen na regel 2)
C++:
1
Application->ProcessMessages();

Hiermee geef je de opdracht om berichten van/naar je programma direct uit te voeren.

Een mooiere oplossing is om de code in een aparte thread te plaatsen. Zo kan het hoofdprogramma GUI-wijzigen blijven doorvoeren.

[ Voor 88% gewijzigd door Icelus op 12-10-2009 11:57 ]

Developer Accused Of Unreadable Code Refuses To Comment


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Omdat de UI pas wordt geupdated NA die functie waarschijnlijk.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • flashin
  • Registratie: Augustus 2002
  • Laatst online: 17-12-2023
spuit elf

[ Voor 96% gewijzigd door flashin op 12-10-2009 11:55 ]


Acties:
  • 0 Henk 'm!

  • Black-Xjuh
  • Registratie: Oktober 2002
  • Laatst online: 14-04 10:23
Icelus schreef op maandag 12 oktober 2009 @ 11:54:
De GUI wordt pas aangepast nadat je methode is afgehandeld. Een snelle oplossing is om de update te forceren met: (plaatsen na regel 2)
C++:
1
Application->ProcessMessages();

Hiermee geef je de opdracht om berichten van/naar je programma direct uit te voeren.

Een mooiere oplossing is om de code in een aparte thread te plaatsen. Zo kan het hoofdprogramma GUI-wijzigen blijven doorvoeren.
Ja de thread oplossing had ik ook al bedacht. Maar deze manier voldoet ook wel voor zolang.

Eigenlijk is het niet eens zo'n probleem als ik maar even die melding kan doorvoeren zodat het niet lijkt alsof er niets gebeurd.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Of je zorgt ervoor dat de open functie niet blocked.

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.


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

farlane schreef op maandag 12 oktober 2009 @ 17:13:
Of je zorgt ervoor dat de open functie niet blocked.
Dus in een thread afvuren.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Nope.

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.


Acties:
  • 0 Henk 'm!

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 15:59
Leg dan eens uit op welke manier? Je hebt een alternatief voor de CreateFile functie? Ook met overlapped I/O blockt CreateFile mogelijkerwijs een tijd bij het openen van een COM poort.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
matthijsln schreef op maandag 12 oktober 2009 @ 17:56:
Leg dan eens uit op welke manier? Je hebt een alternatief voor de CreateFile functie? Ook met overlapped I/O blockt CreateFile mogelijkerwijs een tijd bij het openen van een COM poort.
Geen alternatief voor CreateFile, maar het blocken bij het openen lijkt me onwaarschijnlijk eigenlijk. Wat zou een reden kunnen zijn dat dat gebeurt volgens jou?
Hoe dan?
Door overlapped I/O te gebruiken. Of in geval van een read de timeouts zo te zetten dat de read niet blocked. Of door comm events te gebruiken.

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.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

farlane schreef op maandag 12 oktober 2009 @ 19:55:
[...]

Geen alternatief voor CreateFile, maar het blocken bij het openen lijkt me onwaarschijnlijk eigenlijk. Wat zou een reden kunnen zijn dat dat gebeurt volgens jou?
Een apparaat dat niet reageert / niet (goed) is aangesloten? Bij CreateFile() hoort volgens mij ook gewoon de handshake. Als je 'm niet overlapped opent natuurlijk dan.

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.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Welke handshake? RS-232 handshakes worden gebruik in dataflow; er is geen handshake bij het maken van een connectie.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Oh ok :)

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.


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
.oisyn schreef op maandag 12 oktober 2009 @ 22:02:
[...]

Een apparaat dat niet reageert / niet (goed) is aangesloten? Bij CreateFile() hoort volgens mij ook gewoon de handshake. Als je 'm niet overlapped opent natuurlijk dan.
Een brakke device driver/hardware zou een oorzaak kunnen zijn misschien, maar dan heb je een groter probleem dan een call naar CreateFile die blocked denk ik. ( Het nut van een snappy UI is dan ook ver te zoeken, het niet alsof je de call dan nog kunt afbreken oid )

[edit]
Ik heb het gevoel dat men multithreading ziet als iets waarmee je het verschijnsel van een blocking call kunt tegengaan ( in het bijzonder bij communicatietaken ), terwijl een groot gedeelte van de taken die je daar doet I/O gebonden zijn en multithreading maar weinig gaat toevoegen.

[ Voor 21% gewijzigd door farlane op 12-10-2009 22:34 ]

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.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Wat is het probleem met een I/O blocked thread? Werkt uitstekend, kan ik uit eigen ervaring vertellen. Schaalt niet naar 20.000 TCP/IP sockets misschien, maar dat is hier het doel ook niet.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
MSalters schreef op maandag 12 oktober 2009 @ 22:52:
Wat is het probleem met een I/O blocked thread?
Op zich geen probleem denk ik, je introduceert alleen wel de complexiteit van multithreading in je applicatie die misschien helemaal niet nodig is voor die ene seriele poort die je gebruikt.

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.


Acties:
  • 0 Henk 'm!

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 15:59
MSalters schreef op maandag 12 oktober 2009 @ 22:19:
Welke handshake? RS-232 handshakes worden gebruik in dataflow; er is geen handshake bij het maken van een connectie.
Een virtuele COM poort voor een Bluetooth apparaat is geen brakke device driver maar blockt wel totdat de Bluetooth verbinding is opgezet. De COM poort kan ook ook virtuele COM poort zijn van een serieel naar USB convertor of iets dergelijks.

Je kan er gewoon niet vanuit gaan dat het openen van een seriele poort niet blockt. Het is niet zo dat in de driver specificatie voor het maken van (virtuele of niet, daar is in principe geen verschil tussen) COM poorten staat dat CreateFile() niet mag blocken.

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

farlane schreef op dinsdag 13 oktober 2009 @ 09:26:
Op zich geen probleem denk ik, je introduceert alleen wel de complexiteit van multithreading in je applicatie die misschien helemaal niet nodig is voor die ene seriele poort die je gebruikt.
De complexiteit van een blocked I/O thread is wel een stuk lager dan voor non-blocking IO; dan moet je elke keer kijken of iets gedaan is, eventueel wachten (wat ga je anders doen?) en/of asynchrone callbacks instellen die dan weer parallel met je programma lopen. Ik heb een tijdje met async I/O gewerkt (boost::asio) en dat is nog best lastig soms. Als je weg kan komen met een thread afsplitsen die gewoon alles blocking doet, dan zou ik zeker die weg inslaan.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
matthijsln schreef op dinsdag 13 oktober 2009 @ 14:40:
Een virtuele COM poort voor een Bluetooth apparaat is geen brakke device driver maar blockt wel totdat de Bluetooth verbinding is opgezet. De COM poort kan ook ook virtuele COM poort zijn van een serieel naar USB convertor of iets dergelijks.
Ik zou het logischer vinden dat een BT poort niet word geregistreerd als BT poort indien er geen verbinding is met het apparaat en niet dat hij gaat blocken totdat het BT apparaat na een week een keer zin heeft om in de buurt van je ontvanger te komen, maar ik moet eerlijk zeggen dat ik daar geen ervaring mee heb. Als het zo is als je schetst dan zou ik dat behoorlijk brak vinden tbh.
Same met een USB com poort, die poort is simpelweg niet aanwezig in je systeem totdat het ding wordt ingeplugd en de driver het device heeft aangemaakt.
Je kan er gewoon niet vanuit gaan dat het openen van een seriele poort niet blockt. Het is niet zo dat in de driver specificatie voor het maken van (virtuele of niet, daar is in principe geen verschil tussen) COM poorten staat dat CreateFile() niet mag blocken.
Voor zover ik weet zijn daar inderdaad geen voorschriften voor, wel best practises lijkt me. Ik heb trouwens geen idee of een CreateFile ook overlapped kan.

@Zoijar ea, inderdaad is overlapped io ook niet de meest simpele methode en indien opschalen geen issue is zou het ook niet mijn voorkeur hebben.

Voor mijn eigen applicaties, die toch vaak een statemachine nodig hebben die cyclisch doorlopen moet worden gebruik ik vaak een simpel timertje (of de main loop) en read timeouts die niet of maar heel kort blocked, niet eens overlapped dus. Geen overlapped io, geen threads en blijkt in de praktijk bijzonder goed en robuust te werken. ( Voor mij dan, YMMV )

[ Voor 4% gewijzigd door farlane op 14-10-2009 00:21 ]

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.


Acties:
  • 0 Henk 'm!

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 15:59
farlane schreef op woensdag 14 oktober 2009 @ 00:08:
Ik zou het logischer vinden dat een BT poort niet word geregistreerd als BT poort indien er geen verbinding is met het apparaat en niet dat hij gaat blocken totdat het BT apparaat na een week een keer zin heeft om in de buurt van je ontvanger te komen, maar ik moet eerlijk zeggen dat ik daar geen ervaring mee heb. Als het zo is als je schetst dan zou ik dat behoorlijk brak vinden tbh.
Dat is voor een Bluetooth apparaat helemaal niet logisch. Het is bedoeld als energiezuinig protocol voor mobiele apparaten. Daar hoort ook bij dat je pas een verbinding opzet wanneer er ook echt gebruik van wordt gemaakt. Daarnaast is van de Bluetooth kant seriele poort emulatie meer een soort van socket met een begin en eind.

En ja, zo werkt het nou eenmaal in Windows met de standaard drivers van Microsoft. Als er geen verbinding kan worden opgezet krijg je een GetLastError van "De semafoor is verlopen" na een tijdje.
Ik heb trouwens geen idee of een CreateFile ook overlapped kan.
Nee, daarom vroeg ik ook al naar jouw alternatief voor CreateFile :)

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
matthijsln schreef op woensdag 14 oktober 2009 @ 09:05:
Daarnaast is van de Bluetooth kant seriele poort emulatie meer een soort van socket met een begin en eind.
Waarom dan seriele poort emulatie en niet via de socket API? Klinkt alsof het mappen van een seriele poort op een BT verbinding niet echt lekker past. ( Bij een socket heb je in ieder geval een connect fase wat bij een seriele poort in mijn optiek onzin is )

Iig zou je in het geval wat jij schetst inderdaad geen andere optie hebben dan een thread afsplitsen.

[ Voor 9% gewijzigd door farlane op 14-10-2009 12:12 ]

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.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
farlane schreef op dinsdag 13 oktober 2009 @ 09:26:
Op zich geen probleem denk ik, je introduceert alleen wel de complexiteit van multithreading in je applicatie die misschien helemaal niet nodig is voor die ene seriele poort die je gebruikt.
Nee, nergens voor nodig. Complexiteit van multi-threading treed pas op als je (data) dependencies tussen threads introduceert. Voor een simpele I/O thread kun je volstaan met twee thread-safe queues, en daarvoor is een triviale mutex voldoende. Omdat dit per definitie een leaf node in de mutex hierarchie is, kun je'm negeren bij deadlock analyse. Om die reden is een thread-safe queue een bruikbare abstractie. Ongeveer de enige overweging is of je message parsing&formatting in je I/O thread wil doen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
MSalters schreef op woensdag 14 oktober 2009 @ 12:20:
Nee, nergens voor nodig. Complexiteit van multi-threading treed pas op als je (data) dependencies tussen threads introduceert. Voor een simpele I/O thread kun je volstaan met twee thread-safe queues, en daarvoor is een triviale mutex voldoende. Omdat dit per definitie een leaf node in de mutex hierarchie is, kun je'm negeren bij deadlock analyse. Om die reden is een thread-safe queue een bruikbare abstractie. Ongeveer de enige overweging is of je message parsing&formatting in je I/O thread wil doen.
Maw als je multi threaded gaat werken introduceer je grotere complexiteit in je applicatie ( in meer of mindere mate ) die misschien niet nodig zou zijn.

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.


Acties:
  • 0 Henk 'm!

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 15:59
farlane schreef op woensdag 14 oktober 2009 @ 12:32:
[...]
Maw als je multi threaded gaat werken introduceer je grotere complexiteit in je applicatie ( in meer of mindere mate ) die misschien niet nodig zou zijn.
Ja, maar als je twee dingen tegelijk wilt (GUI en I/O) moet je nou eenmaal complexiteit introduceren :) Linksom (threads) of rechtsom (async)

Jouw voorgestelde methode introduceert natuurlijk ook dingen waar je van bewust moet zijn (gevaar van busywaits bij te lage timeouts, of GUI lag bij te hoge timeouts, wat is de schaalbaarheid etc). Dat is ook extra complexiteit.

Het is naar mijn mening zo dat als je een goede programmeur bent je bekend bent met hoe je threads, async of iets anders goed (en dus duidelijk / begrijpelijk / niet overmatig complex) moet implementeren en je keuze dus moet maken op basis van de andere consequenties van de methodes; zoals performance, aantal verbindingen, communicatie met gui layer, geheugengebruik, e.d. en dus de juiste tool for the job moet kiezen ;)
Pagina: 1