Uit de cursus: Programmeerconcepten voor Python

Polling

- Er zullen momenten zijn waarop u een programma nodig heeft om te detecteren dat een gebeurtenis heeft plaatsgevonden en vervolgens op die gebeurtenis te reageren door een bepaalde actie uit te voeren. Om dat te bereiken, zijn er twee benaderingen die u kunt gebruiken: polling of event-driven programmeren. Met de polling-methode controleert een programma continu en controleert en controleert en controleert actief of een bepaalde voorwaarde zich voordoet, zoals een knop die wordt ingedrukt, en wanneer het ziet dat de voorwaarde is opgetreden, zal het een passende actie uitvoeren. Mijn huis is klaar voor mijn vrienden, dus nu wacht ik alleen nog tot de pizzabezorger er is. Als de pizzaman arriveert, moet ik de juiste actie ondernemen door de deur te openen en de pizza te pakken. Dus hoe weet ik wanneer de pizzaman op de veranda staat om mijn pizza te halen? Nou, ik zou de polling-methode kunnen proberen, en om dat te doen, moet ik van mijn bed opstaan. Dan ga ik de trap af. (deur klikt) Ik kijk of hij er is, nog niet. (deur klikt) Dus dan ga ik terug de trap op en dan ga ik weer loungen, maar zodra ik weer ga liggen, moet ik meteen weer opstaan en kijken of hij hier is. Ik ga de trap weer af. (deur klikt) Nee, nog steeds niet hier. (deur klikt) Terug de trap op ga ik, ga liggen, sta op, nog een keer de trap af, nog niet. (deur klikt) Weer omhoog, omlaag, omhoog, weer omlaag. (deur klikt) Nee, en weer de trap op. Oef, dat is vermoeiend! Zoals u kunt zien, is polling geen erg efficiënte methode. Het kost me veel energie om deze trappen op en af te rennen, om te controleren op een status die zelden voorkomt. Het weerhoudt me er ook van om iets anders te doen met mijn zaterdagmiddag. Een computertoepassing die een polling-routine implementeert, gebruikt veel cycli, waarbij wordt gecontroleerd op die zelden voorkomende status, en eenvoudige, low-level programma's zoals je zou kunnen schrijven voor een microcontroller met een taal als C, die polling gebruiken om softwaregestuurde I/O uit te voeren, kunnen perfect acceptabel zijn. Als het programma het enige is dat op de microcontroller draait, maakt het niet uit of we veel cycli besteden aan peilingen. Applicaties en talen op een hoger niveau, zoals Python of Java, reageren meestal op gebeurtenissen van zaken als een grafische gebruikersinterface. Daarvoor zou het gebruik van een polling-routine behoorlijk verspilling zijn, maar er kunnen momenten zijn waarop polling uw enige optie is. Laten we dus eens kijken naar enkele voorbeeldcode die polling in Python implementeert. Dit voorbeeldscript geeft het scenario weer dat we net zagen toen ik de trap op en af rende om te zien of de pizzabezorger was gearriveerd. Bovenaan het script maken we een variabele met de naam hongerig op regel 3, die mijn huidige status aangeeft en deze wordt geïnitialiseerd naar Waar omdat ik honger heb. Daarom heb ik pizza nodig. Daarna komt het programma in een while-lus op regel 5, die continu zal worden uitgevoerd zolang honger nog waar is. Binnen de lus open ik de voordeur, die we simuleren door een tekstbestand te openen met de naam front_door.txt. De open-functie retourneert een bestandsobject, dat gebonden is aan de variabelenaam voordeur op regel 7. Laten we eens kijken naar dat tekstbestand, dat is opgenomen in dezelfde map met de oefenbestanden. Dit bestand bevat de dingen die buiten mijn voordeur staan. Ik heb momenteel een welkomstmat en een deurbel, maar helaas geen pizzabezorger. Terugkijkend op het script na het openen van het tekstbestand, controleert de if-instructie op regel 9 of de stringbezorger al dan niet bestaat in dat front_door tekstbestand. Als dat zo is, dan geef ik een kreet van vreugde om aan te kondigen dat de pizza hier is en honger naar Vals te maken. Als de bezorger echter niet bij de voordeur is, dan zeg ik met een zeer hongerige stem: "Nog niet..." Daarna maak ik de lus af door de voordeur te sluiten, wat wordt gesimuleerd door het bestandsobject op regel 16 te sluiten. Als de pizza is aangekomen en ik heb geen honger meer, dan gaat de while-lus eruit na het sluiten van de deur. Anders, zoals we eerder zagen, zal de while-lus opnieuw en opnieuw en opnieuw en opnieuw worden uitgevoerd terwijl ik blijf controleren. Om dit script nu uit te voeren vanuit de map waarin het leeft, zodat het het front_door tekstbestand kan vinden, klik ik met de rechtermuisknop op de bovenliggende map binnen VS Code, selecteer ik de open en geïntegreerde terminaloptie en vervolgens roep ik Python aan om het script uit te voeren. We kunnen zien dat de while-lus zo snel mogelijk heen en weer loopt om te controleren of de pizza aankomt. Omdat die routine non-stop draait, besteden we in feite een hele processorkern om te controleren of de pizzapersoon beneden is, wat niet erg efficiënt is. We kunnen die pizzapersoon laten aankomen door het tekstbestand van de front_door aan te passen zodat er een bezorger in zit. Zodra die wijziging in het bestand is opgeslagen, ziet de polling-routine dat ze zijn aangekomen. Ik zal aankondigen dat de pizza hier is en dat de while-lus zal eindigen en eindigen. Dit voorbeeld laat zien waarom u geen freerunning while-lus moet gebruiken om een polling-routine te implementeren. Wanneer u een polling-routine maakt, is het meestal een goed idee om een soort vertragingsmechanisme in de lus op te nemen om te voorkomen dat deze non-stop wordt uitgevoerd, wat CPU-bronnen kan verspillen en kan voorkomen dat andere dingen worden uitgevoerd, of ze op zijn minst vertragen. In Python kunnen we dat doen door de tijdmodule bovenaan ons script te importeren. Dan voegen we de time.sleep-functie helemaal aan het einde van deze while-lus toe. Dit zorgt ervoor dat het programma één seconde wacht wanneer het bij die regel aankomt. Nadat ik de voordeur heb gesloten, rust ik een seconde uit voordat ik opnieuw ga controleren. Laten we, voordat we dat script uitvoeren, de pizzabezorger uit het tekstbestand van de front_door verwijderen en vervolgens Python aanroepen om dat script opnieuw uit te voeren vanuit de terminal. Het is niet helemaal duidelijk als je alleen naar de output kijkt, maar nu draait de while-lus niet non-stop op volle snelheid. Het is slechts één keer per seconde controleren of de pizzapersoon arriveert, en door dat te doen, overweldigen we de CPU niet. De reden dat dit werkt, is omdat de slaapfunctie een mechanisme gebruikt dat een interrupt wordt genoemd, waardoor het programma kan slapen op een manier die geen normale CPU-cycli verspilt, en dan wordt het na een seconde wakker om door te gaan met uitvoeren.

Inhoud