Toon posts:

[C++] try-catch met tijd?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

Ik heb een vraagje .. Bestaat er in C++ een try catch blok die een bepaalde tijd kan gelden?

Bijvoorbeeld:

- probeer 5 seconden te wachten op een seriele byte
- indien langer dan 5 seconden = catch

nu doe ik dit met een tellertje, maar dit is dan terug pc afhankelijk?

bedankt!

  • DaCoTa
  • Registratie: April 2002
  • Laatst online: 30-11 21:02
Volgens mij moet je een timeout kunnen zetten of de seriele input methodes. Zoals je het nu wil doen is het andersom.

[ Voor 4% gewijzigd door DaCoTa op 14-05-2007 14:00 ]


  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 00:18

Gonadan

Admin Beeld & Geluid, Harde Waren
Verwijderd schreef op maandag 14 mei 2007 @ 13:59:
Hallo,

Ik heb een vraagje .. Bestaat er in C++ een try catch blok die een bepaalde tijd kan gelden?

Bijvoorbeeld:

- probeer 5 seconden te wachten op een seriele byte
- indien langer dan 5 seconden = catch

nu doe ik dit met een tellertje, maar dit is dan terug pc afhankelijk?

bedankt!
Volgens mij bestaat het niet. En een tellertje is inderdaad pc afhankelijk.
Zoals DaCoTa al zegt denk ik dat je de oplossing ergens anders moet zoeken. :)

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Verwijderd

De enige mogenlijkheid die ik zie, is dat jet het ontvangen van die byte in een apparte thread doet.

IN de thread die de exception moet krijgen kun je de andere thread opstarten, deze 5 seconden geven om een byte te ontvangen ( vb met een timedwait).

Als binnen deze tijd de ontvangende thread een byte krijgtgeeft deze een signaal aan de wachtende thread.
Eens de 5 seconden om zijn kan de ontvangende thread gekilled worden en kan de exception worden gegooid

Niet de meest efficiente en propere mannier, maar het maakt een 'getimede' try catch wel mogelijk

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
ik denk idd dat dit met een aparte thread moet kunnen. ik heb niet veel verstand van multithreading maar het lijkt me te moeten kunnen.

set een timer, in een oneindige loop kijk je steeds of er een byte gevonden is. als timer groter is dan 5 ga je naar de catch op het moment dat je ontvangt set je timer weer 0.
Misschien zelfs met een event handler te doen, weet echter niet of die bestaan in c++ (meer dan een aantal regels heb ik nooit ge-c++-ed.

Hoezo is een tellertje eigenlijk pc afhankelijk?

  • Soultaker
  • Registratie: September 2000
  • Nu online
Dit is in C++ niet onmogelijk, omdat je niet zomaar een functie halverwege kunt afbreken en verwachten dat objecten nog in een consistente toestand zijn. In C (en dus in C++) kun je wel iets doen met signal handlers, maar je moet heel voorzichtig zijn om dan geen ongewenst gedrag te introduceren. In de prakijk is het gebruik van process signals in combinatie met C++ niet wenselijk.

Overigens kun je wel iets doen met een alarm-signal (die I/O calls onderbreekt) maar dat is ten eerste problematisch vanwege race conditions (valt in de praktijk mee, als je een grote time-out gebruikt) en ten tweede werkt het niet goed in multithreaded programma's.

Gelukkig is er een andere mogelijkheid: gebruikt select().

[ Voor 22% gewijzigd door Soultaker op 14-05-2007 20:08 ]


  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 01:48

Reptile209

- gers -

Mischa_NL schreef op maandag 14 mei 2007 @ 19:06:

Hoezo is een tellertje eigenlijk pc afhankelijk?
code:
1
2
3
4
for(i := 0; i<100000; i++)
  {
    DoStuff;
  }

Doe dit maar eens op een 8086 en op je huidige PC en neem de tijd maar eens op :).

Een alternatief "tellertje" kan bestaan uit een while-lus waarin je met getTickCount() kijkt of je al aan 5 seconden zit. Da's niet perfect nauwkeurig, maar close enough voor de meeste toepassingen. In de lus moet je dan dus checken op het ontvangen van data (non-blocking). Let wel op dat dit geheel je programma verder blockt, tenzij het weer in een aparte thread staat...

Zo scherp als een voetbal!


  • Soultaker
  • Registratie: September 2000
  • Nu online
Beetje jammer dat je dan wel 100% CPU trekt, terwijl je niets zinnigs doet. Dan lijkt me de oplossing met select() heel wat beter.

  • DaCoTa
  • Registratie: April 2002
  • Laatst online: 30-11 21:02
Bestaat Thread.sleep() niet meer? Of ben ik nu te java minded?

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 23:31

.oisyn

Moderator Devschuur®

Demotivational Speaker

En dan, altijd x seconde wachten en dan pas erachter komen dat je de data in de eerste milliseconde al binnen had? :)

Maar goed, in C++ kan het niet, simple as that. Je zult dus moeten bouwen op OS-specifieke functies. In *nix heb je select(), onder Windows moet je eens kijken naar overlapped IO.

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.


  • MisterData
  • Registratie: September 2001
  • Laatst online: 27-11 20:42
Je zult even moeten vertellen op welk OS je werkt en welke API's je gebruikt denk ik :) Onder Windows zou ik inderdaad een aparte thread starten. Met API's als WaitForSingleObject en events kun je wachten totdat je thread een bepaald event zet (event 'io klaar' bijvoorbeeld) of totdat de timeout voorbij is... :)

  • Mischa_NL
  • Registratie: Mei 2004
  • Laatst online: 01-02-2023
DaCoTa schreef op maandag 14 mei 2007 @ 20:24:
Bestaat Thread.sleep() niet meer? Of ben ik nu te java minded?
lijkt me ook
doe een sleep van 5000ms en check via peek of je een byte te pakken hebt? zo ja: hoppa, nee -> throw exception.
Of denk ik nu heel gek/simpel?


code:
1
2
3
4
for(i := 0; i<100000; i++)
  {
    DoStuff;
  }

dat slaat natuurlijk ook nergens op. Een tellertje is geen timer. ik zou voor de thread.sleep gaan maar, je kunt het natuurlijk ook met QueryPerformanceFrequency en QueryPerformanceCounter oplossen en deze tot 5000 ms laten lopen en steeds peeken. Zo heb je je byte gelijk maar heb je wel een 100% cpu load, wat niet de bedoeling is lijkt me. Je kunt dan steeds een sleep doen van 200ms oid naar gelang je je byte zo snel mogelijk wilt hebben.

[ Voor 44% gewijzigd door Mischa_NL op 14-05-2007 23:29 ]


  • Soultaker
  • Registratie: September 2000
  • Nu online
@DaCoTa en Mischa_NL: het probleem daarmee is dus dat je nodeloos een vertraging introduceert voor het registreren van een event. Je kunt op die manier wel een redelijke trade-off maken tussen CPU usage en maximale vetraging, dus het is een aardige methode als niets anders werkt, maar het blijft nogal inefficient vergeleken met select(), of een andere API waarmee je applicatie gewoon niet runnable is totdat er een event optreed óf de tijd verstrijkt.

Het wordt helemaal vervelend als je gaat bedenken wat er gebeurd als er een heleboel threads tegelijk runnen, die allemaal verschillende memory pages accessen, daardoor nodeloos veel page faults triggeren, etcetera. Bij een simpele test merk je het effect daarvan niet, maar het is een waardeloze manier om een event-based applicatie op te zetten.

Er is een goede reden dat Windows een event loop gebruikt, praktisch alle OSes standaard blocking I/O doen, en er system calls als select() bestaan.
Pagina: 1