Ohjelmoinnin peruskurssien laaja oppimäärä

Samankaltaiset tiedostot
Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Palomuurit. Palomuuri. Teoriaa. Pakettitason palomuuri. Sovellustason palomuuri

Kiertokysely. Sulautetut järjestelmät Luku 2 Sivu 1 (??)

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Pythonin Kertaus. Cse-a1130. Tietotekniikka Sovelluksissa. Versio 0.01b

Ohjelmoinnin perusteet Y Python

3. Kuljetuskerros 3.1. Kuljetuspalvelu

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 6: Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Luento 5. Timo Savola. 28. huhtikuuta 2006

SSH Secure Shell & SSH File Transfer

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

ELEC-C7241 Tietokoneverkot Ohjelmointiprojekti

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

TCP/IP-protokollat ja DNS

Tehtävä 2: Tietoliikenneprotokolla

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Harjoitustyö: virtuaalikone

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

AJAX-konsepti AJAX. Asynkronisuus. Nykyisten web-ohjelmien ongelmia. Asynchronous JavaScript And XML

811120P Diskreetit rakenteet

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1

KServer Etäohjaus Spesifikaatio asiakaspuolen toteutuksille

Laitteessa tulee olla ohjelmisto tai uudempi, tarvittaessa päivitä laite

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Tutoriaaliläsnäoloista

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Salausmenetelmät (ei käsitellä tällä kurssilla)

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

Ohjelmoinnin peruskurssi Y1

OSI ja Protokollapino

Ohjelmoinnin peruskurssi Y1

Tietokone. Tietokone ja ylläpito. Tietokone. Tietokone. Tietokone. Tietokone

Netemul -ohjelma Tietojenkäsittelyn koulutusohjelma

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

Ohjelmoinnin perusteet Y Python

Graafisen käyttöliittymän ohjelmointi Syksy 2013

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin perusteet Y Python

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Zeon PDF Driver Trial

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 5: Python

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Tietoliikenne II (2 ov)

Ohjelmoinnin perusteet Y Python

Tikon Ostolaskujenkäsittely versio SP1

Tietotekniikan valintakoe

Unix-perusteet. Tulostaminen

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä, kevät

Verkko-ohjemointia. TCP vs. UDP Socket, ServerSocket Datagrammit RMI

4. Luento: Prosessit ja säikeets. Tommi Mikkonen,

Ohjelmoinnin perusteet Y Python

Antti Vähälummukka 2010

Ohjelmoinnin peruskurssi Y1

Olet tehnyt hyvän valinnan hankkiessasi kotimaisen StorageIT varmuuskopiointipalvelun.

12. Näppäimistöltä lukeminen 12.1

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin peruskurssien laaja oppimäärä

Unix-perusteet. Tiedosto-oikeudet

3. Kuljetuskerros 3.1. Kuljetuspalvelu

Ohjelmoinnin peruskurssi Y1

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

BaseMidlet. KÄYTTÖOHJE v. 1.00

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Linux palomuurina (iptables) sekä squid-proxy

Transkriptio:

Ohjelmoinnin peruskurssien laaja oppimäärä Luento 5: Verkko-ohjelmointi, tapahtumapohjainen ohjelmointi Riku Saikkonen (osa kalvoista on suoraan ei-laajan kurssin luennoista) 11. 2. 2013

Sisältö 1 Verkko-ohjelmointia: socketit 2 Useammasta paikasta lukeminen 3 Tapahtumapohjainen ohjelmointi

(ei-laajan kurssin kalvo: luento 5 sivu 21) Yksinkertainen palvelin import socket # Import socket module server = socket.socket() # Create a socket object host = socket.gethostname() # Get local machine name port = 12345 # Reserve a port for your service. server.bind((host, port)) # Bind to the port server.listen(5) # Now wait for client connection. while True: client, addr = server.accept() # Establish connection with client. print 'Got connection from', addr infile = open('esimerkki.txt', 'r') for line in infile: client.send(line) client.close() # Close the connection 14:58

(ei-laajan kurssin kalvo: luento 5 sivu 22) Ja asiakas import socket import StringIO # Import socket module client = socket.socket() # Create a socket object host = socket.gethostname() # Get local machine name port = 12345 # Reserve a port for your service. client.connect((host, port)) message = StringIO.StringIO() chunk = client.recv(10) while chunk: message.write(chunk) chunk = client.recv(10) print message.getvalue() client.close() # Close the socket when done 14:58

Millaisia verkkoyhteyksiä on? edellinen esimerkki käytti Internetin TCP/IP-protokollaa se on tietovirtapohjainen (stream) eli avattu yhteys näyttää tiedostolta (sisään ja ulos kulkee jono tavuja) oikeasti data liikkuu paketeissa (usein 1500 tavua), joita voi kadota tai joiden järjestys voi muuttua matkalla TCP-protokolla järjestää paketit ja pyytää tarvittaessa uudelleenlähetyksiä (ei näy ohjelmalle) toinen, harvinaisempi vaihtoehto on UDP/IP pakettipohjainen (datagram): lähetetään ja vastaanotetaan tavujonojen sijaan kokonaisia paketteja pakettien lähetykseen ja vastaanottoon on useimmissa kielissä omat funktionsa ohjelma saa paketit kokonaisina ja sitä mukaa kun niitä tulee siis paketteja voi jäädä tulematta tai tulla eri järjestyksessä käytetään esim. reaaliaikaista ääni- ja videodataa siirrettäessä muutama muukin tämän tason protokolla on

Portit ja yhteydet yhteyden muodostaminen TCP:ssä ja UDP:ssä: 1 Palvelin kuuntelee (listen) oman IP-osoitteensa (jonkin tai kaikkien niistä) tiettyä porttia, esim. 12345 2 Asiakas ottaa yhteyden (connect) tähän IP-osoitteeseen ja porttiin 3 Palvelin hyväksyy (accept) tämän yhteydenottopyynnön (voi hyväksyä useammankin pyynnön: niistä tulee erilliset yhteydet) yhteydenmuodostuksen jälkeen yhteys on symmetrinen: kumpi tahansa voi lähettää dataa toiselle tai sulkea yhteyden portti (port) on numero väliltä 165535 useimmiten kuunnellaan tietyssä portissa, joka kuuluu jollekin palvelulle (esim. useimmat HTTP-palvelimet portissa 80) avattu yhteys (connection) on nelikko, jossa on kummankin pään IP-osoite ja kummankin pään valitsema portti asiakas valitsee itselleen yleensä satunnaisen portin porttiparilla erotetaan samojen koneiden väliset yhteydet toisistaan esim. WWW-palvelimeen voisi olla yhtäaikaiset yhteydet (12.12.12.12, 1025, 1.2.3.4, 80) ja (12.12.12.12, 1524, 1.2.3.4, 80)

Nimipalvelin TCP/IP ja UDP/IP toimivat IP-osoitteilla (numeroita) koneiden tai palveluiden nimet muutetaan IP-osoitteiksi kysymällä niitä nimipalvelimelta (domain name server) Internetissä on hierarkia nimipalvelimia, joilta nimiä kysytään esim. www.aalto.fi: juurinimipalvelin (root server) tietää fi-nimipalvelimen osoitteen, joka tietää aalto.fi-nimipalvelimen osoitteen, joka tietää www.aalto.fi-koneen osoitteen tämä on harvoja osia Internetistä, joka on hallinnollisesti keskitettyä esim. fi-nimipalvelin päättää kaikista.fi-päätteisistä osoitteista (vaikka se yleensä delegoi päätökset alemman tason palvelimille) kuormitussyistä ylempien tasojen nimipalvelimia on monta samanlaista (esim. juurinimipalvelimia kymmeniä) käytännössä lähiverkossa on melkein aina apunimipalvelin, jolta voi kysellä nimiä ja joka kysyy niitä eteenpäin muilta ja tallettaa kyselyiden tulokset välimuistiinsa, joten samojen koneiden nimiä ei tarvitse ei tarvitse koko ajan kysellä periltä asti

Nimipalvelin ohjelmoijan näkökulmasta nimipalvelin ja siihen liittyvät protokollat piilotetaan enimmäkseen ohjelmoijalta: joko kirjastoissa on kutsu, jolla voi tehdä nimipalvelukyselyn tai yhteydenmuodostuskomennolle voi antaa IP-osoitteen sijaan nimen käytännön rajapintaongelma: useimmiten nimipalvelukysely jää odottamaan vastausta (blocking) siis ohjelma pysähtyy siksi aikaa kirjastorajapinnat, joissa ohjelma voisi tehdä jotain odotuksen aikana, ovat harvinaisia jos tämä on ongelma, nimipalvelukyselyt voi tehdä esim. eri säikeessä jotkin ohjelmat, esim. WWW-selaimet, käynnistävät oman aliprosessin nimipalvelukyselyitä varten (se pitää lisäksi tulokset tallessa muistissaan)

TCP:n päällä olevat protokollat TCP/IP siis tarjoaa yhteyden, jossa voi siirtää vapaamuotoista dataa (tavuja tai merkkejä) edestakaisin sen päälle on Internetissä tehty paljon sovellustason protokollia esim. HTTP, jossa asiakas pyytää webbisivua (avaa palvelimeen yhteyden ja lähettää URLin tietyssä muodossa) ja palvelin vastaa sivun sisällöllä tai NNTP, jolla luetaan ja kirjoitetaan nyyssejä yhden rivin pituisilla ASCII-komennoilla nämä on dokumentoitu ns. RFC-dokumenteissa, joista osa on valittu Internet-standardeiksi useimmat ovat asiakaspalvelin-tyyppisiä joskus käytetään myös peer-to-peer-palveluita, joissa molemmat päät ovat samanarvoisia yhteydenmuodostus on näissä monimutkaisempaa, varsinkin palomuurien ja osoitemuunnosten (NAT) läpi käytetään esim. joissain verkkopeleissä ja IP-puheluissa

Paikalliset socketit periaatteessa socketit eivät ole vain Internet-yhteyksiä varten varsinkin Unix/Linux-koneissa niitä käytetään myös koneen sisäiseen kommunikointiin ohjelmien välillä Unix domain socket on kuten TCP, mutta paikallinen: portin tilalla on (yleensä) tiedoston nimi, jossa kuunnellaan ja johon otetaan yhteyttä tiedosto on tyypiltään socket ( s ls-komennossa) muodostettu yhteys toimii kuten TCP, mutta koneen sisällä lisäksi yhteydestä saa selville sen toisen pään käyttäjänimen (sillä tai tiedoston oikeuksilla voi rajoittaa sockettiin pääsyä) etuna on varsinkin viimeinen: UDP- ja TCP-yhteyksiin pääsee ainakin koko sama kone, tavallisesti myös koneen ulkopuolelta UDP- ja TCP-yhteydet voi rajoittaa samasta koneesta (mutta muiltakin käyttäjiltä) tuleviksi vaihtamalla kuunneltava osoite (listen address, bind address) localhost-osoitteeksi 127.0.0.1

Vinkkejä kokeiluun komentoriviohjelmilla nc ja socat voi avata yksittäisiä verkkoyhteyksiä kummin päin tahansa ohjelmilla host ja dig voi tehdä nimipalvelukyselyjä omalla koneella (ylläpito-oikeuksilla) esim. ohjelmalla tcpdump voi seurata koneen lähettämiä ja vastaanottamia paketteja varoitus: kuuntelevaan TCP- tai UDP-sockettiin pääsee koko maailma! paitsi jos palomuuri sattuu estämään (silloinkin pääsee sama kone ja yleensä koko lähiverkko) kokeilut kannattaa tehdä esim. kotikoneella, joka on irti verkosta varsinkin kuunteleva ja pitkään päällä oleva palvelin on tietoturvariski (oleta, että verkosta tuleva syöte on vihamielistä!) Aalto-koneilla Työaseman tai palvelimen ulkopuolelle näkyvien palveluprosessien pystyttäminen edellyttää tietojärjestelmän omistajan lupaa. (käyttöpolitiikka 3. 6. 2010) lisää verkkoyhteyksistä esim. kurssin T-110.2100 luentokalvoilta

(ei-laajan kurssin kalvo: luento 5 sivu 23) Verkkoyhteydet Socket-kirjaston päälle on rakennettu muita kirjastoja, jotka helpottavat asioiden tekemistä. Esim. urllib on tiedostojen hakuun www:stä import urllib infile = urllib.urlopen('http://www.cse.hut.fi/fi/opinnot/t1061215/'\ + '2012_external/harjoitukset/kierros_3x/harj_1/game.txt') print infile.read() 14:58

(ei-laajan kurssin kalvo: luento 2 sivu 19) Security injections Seuraava materiaali löytyy kokonaisuudessaan: http://triton.towson.edu/~cssecinj/secinj/?page_id=170 Kolme tärkeää turvallisuusriskiä Kokonaislukuvirheet Kun arvo on liian suuri muuttujaan Ei ongelma Pythonissa Syötteen oikeellisuus Syötteen oikeellisuutta ei tarkasteta Puskurin ylivuoto Sijoitetaan tietoa muuttujalle varatun alueen ulkopuolelle 11:31 Ei ongelma Pythonissa, aiheuttaa virheen

(ei-laajan kurssin kalvo: luento 2 sivu 20) Syötteen oikeellisuus Ohjelman syöte voi olla turvariski ja vakavan virheen syy Kaikkia syötteitä pitäisi käsitellä mahdollisina vaaratekijöinä Oikein muotoiltu syöte voi saada ohjelman suorittamaan laittomia käskyjä Jos syötteen tyyppiä, määrää ja rakennetta ei tarkisteta, riski on olemassa. 11:31

(ei-laajan kurssin kalvo: luento 2 sivu 23) Miten tarkistan syötteen? Tarkista kaikki syötteet Lukualue? Järkevä? Ongelma-arvo? (esim. nolla jakajaan) Muoto? Reagoi virhelliseen syötteeseen oikein Virheestä pitää toipua ja kysyä uudelleen tai muuten jatkaa eteenpäin. Väärän syötteen katkaiseminen tai muotoilu sopivaksi saattaa aiheuttaa lisäharmia 11:31

Sisältö 1 Verkko-ohjelmointia: socketit 2 Useammasta paikasta lukeminen 3 Tapahtumapohjainen ohjelmointi

Ei-blokkaava I/O normaalisti luku tai kirjoitus siis jää tarvittaessa odottamaan eli blokkaa (blocks) ei-blokkaava (non-blocking) I/O toimii useimmissa kielissä joko niin, että lukumetodi/funktio palaa heti ja kertoo lukeneensa 0 tavua, jos dataa ei ollut tai niin, että erillinen metodi/funktio kertoo, onko dataa saatavilla kirjoitusmetodi vastaavasti kertoo, että sai 0 tavua kirjoitettua mutta käytännössä kirjoitukset ovat melkein aina puskuroituja jossain (esim. käyttöjärjestelmässä tai laitteissa), jolloin 0 tavua tarkoittaa että kirjoituspuskuri on täynnä blokkaavassa I/O:ssa kirjoituskin voi blokata, jos puskuri on täynnä ongelmana on, että jos lukeminen tai kirjoittaminen ei jää odottamaan, ohjelman pitää yleensä yrittää sitä uudelleen jatkuvasti esim. silmukassa useimmiten parempi ratkaisu on select (josta seuraavaksi)

Useammasta paikasta lukeminen entä jos ohjelma haluaa lukea monesta paikasta sitä mukaa kun niistä tulee dataa? esim. useammasta auki olevasta verkkoyhteydestä tai (Unixissa) tiedostoista, laitteista, aliprosesseilta tms. tyypillisesti joko jaetaan ohjelma useaan säikeeseen niin että jokainen lukee vain yhtä datalähdettä tai rajapinnassa on funktio, joka tutkii useampaa datalähdettä ja kertoo, mistä niistä on juuri nyt saatavilla dataa tämän nimi on usein select tai poll tätä pitää kutsua silmukassa, jossa tehdään jotain kaikelle saatavilla olevalle datalle jos mistään ei tule dataa, se jää odottamaan vähäksi aikaa (aikarajan voi antaa kutsussa) tarkempia ohjeita Pythonin selectistä: http://docs.python.org/howto/sockets.html ja http://docs.python.org/library/select.html

select-esimerkki: apufunktioita chatserver.py import socket import select class Client(object): def init (self, sock, addr): self.sock = sock self.addr = addr self.wpos = 0 clients = [] chatbuf = bytearray('welcome\n') def findclient(sock): return [c for c in clients if c.sock == sock][0] def removeclient(sock): global chatbuf sockc = findclient(sock) chatbuf += '\n[closed ' + repr(sockc.addr) + ']\n' clients.remove(sockc) def addclient(sock, addr): global chatbuf chatbuf += '\n[connect from ' + repr(addr) + ']\n' clients.append(client(sock, addr))

select-esimerkki: pääohjelma chatserver.py def main(): global chatbuf server = socket.socket() server.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1) server.bind(('', 12345)) server.listen(10) while True: readers = [server] + [c.sock for c in clients] writers = [c.sock for c in clients if c.wpos < len(chatbuf)] rr, rw, err = select.select(readers, writers, readers) for e in err: removeclient(e) e.close() for r in rr: if r == server: clientsock, addr = r.accept() addclient(clientsock, addr) else: data = r.recv(1024) if len(data) == 0: removeclient(r) r.close() chatbuf += data for w in rw: cw = findclient(w) sent = cw.sock.send(chatbuf[cw.wpos:]) cw.wpos += sent

Sisältö 1 Verkko-ohjelmointia: socketit 2 Useammasta paikasta lukeminen 3 Tapahtumapohjainen ohjelmointi

Tapahtumiin perustuva lukeminen monesta paikasta lukemisen ongelmaan on myös toisenlainen ratkaisu: lukemisen voi kääntää toisin päin ei tehdäkään niin että ohjelma lukee halutessaan dataa jonkinlaisella read-funktiolla eikä edes omassa selectiä käyttävässä silmukassa vaan että ohjelma rekisteröi rajapinnalle callback-funktion (takaisinkutsun), jota rajapinta kutsuu aina kun lisää dataa on saatavilla siis: normaalisti ohjelma vetää rajapinnalta lisää dataa silloin, kun ohjelmalle sopii; mutta tässä menetelmässä rajapinta työntää ohjelmalle dataa silloin, kun sitä on saatavilla tällaisen rajapinnan huono puoli on, että datan käsittely tapahtuu eri paikassa kuin lukemisen käynnistäminen, joten koodin etenemistä on vaikeampi seurata

Esimerkki tapahtumiin perustuvasta lukemisesta wget-ohjelman tiedonsiirron etenemistä kuvaava palkki (progress bar) on olio, jonka update-metodia muu ohjelma kutsuu aina kun siirto etenee wget-1.12/src/progress.c metodi saa kaksi argumenttia: howmuch = montako tavua edellisen kutsun jälkeen on saatu, ja dltime = kauanko siirto on tähän mennessä kestänyt muu ohjelma siis työntää tälle oliolle dataa (tavumääriä), ja olio päivittää palkkia aina kun tiedonsiirto on edennyt riittävästi toinen vaihtoehto olisi, että palkin piirtämistä varten olisi silmukka, joka kysyy muulta ohjelmalta säännöllisesti, kuinka paljon dataa on tullut, ja piirtää palkin tämän mukaan tämä on esimerkki ohjelman sisäisestä tapahtumarajapinnasta tyypillisemmin jokin ohjelman ulkopuolinen kirjasto haluaa työntää eikä vetää dataa tai ohjelman sisällä on yksi select-silmukka joka kutsuu ohjelman funktioita pienissä paloissa

Tapahtumapohjaisuus graasissa käyttöliittymissä useimmiten graasissa ohjelmissa ohjelman suoritusmalli on erilainen kuin tavallisissa ohjelman kannalta katsottuna (yksinkertaistaen): main-funktiota tms. ei ole (tai se tekee vain alustuksen ja hyppää GUI-kirjaston pääsilmukkaan) koodista ei näy suoritusjärjestystä, jossa asiat tapahtuvat vaan ohjelma toimii pelkästään reagoimalla yksittäisiin tapahtumiin (event, joskus signal) esim. käyttöliittymän napin painaminen käynnistää tätä tapahtumaa käsittelevän koodin ei siis niin päin, että koodin keskellä olisi read-kutsu tms., joka jäisi odottamaan ja palauttaisi käyttäjältä saadun syötteen tapahtumankäsittelijän pitää usein päätellä, missä tilassa ohjelma on (eli mitä napin pitäisi nyt tehdä) useimmiten yksittäiset tapahtumankäsittelijät ovat melko yksinkertaisia ja lyhytkestoisia

Mitä oikeasti tapahtuu? miten edellä kuvattu tapahtumapohjainen suoritusmalli toteutetaan? GUI-ohjelmassa on main, joka luo käyttöliittymäkomponentit ja jää lopulta silmukkaan (ns. event loop) odottamaan tapahtumia tämä silmukka on normaalisti GUI-kirjaston sisällä eli ei suoraan näy itse ohjelmassa silmukka lähettää kunkin tapahtuman sen käsittelijälle tapahtumankäsittelijä on funktio tai metodi, jonka ohjelmoija on esim. käyttöliittymäkomponenttia luodessaan antanut tee nappi, jonka painalluksista kutsutaan tätä funktiota tällainen funktio on nimeltään takaisinkutsu (callback function) sitä ei (yleensä) kutsuta suoraan ohjelmasta käsin tapoja ajatella: suoritus on asynkronista (ei siis tahdissa käsky kerrallaan) tai reaktiivista (reagoidaan tapahtumiin eikä jäädä kesken koodin odottamaan vastausta)

Peräkkäin vai yhtäaikaa? yleensä tapahtumankäsittelijöitä kutsutaan peräkkäin ei siis yhtäaikaa eli rinnakkain tyypillisesti käyttöliittymä ei reagoi, kun suoritus on tapahtumankäsittelijäfunktion sisällä joten funktion on syytä olla nopea entä jos GUI-ohjelmassa haluaa tehdä jotain pitkäkestoista? kirjastoissa on erikseen tapa määritellä taustalaskentaa (kutsu tätä aina kun tapahtumia ei ole saatavilla) sekä ajastettuja tapahtumia (kutsu tätä sekunnin välein) mutta näitäkin kutsutaan muun tapahtumakäsittelyn joukossa, joten yksittäisen funktion suoritus ei saa kestää kauaa (muuten käyttöliittymä jää jumiin siksi aikaa) pitkäkestoinen laskenta pitää siis paloitella lyhyisiin osiin toinen tapa on käyttää rinnakkaisuutta (josta myöhemmin)

I/O GUI-kirjastoissa entä jos graanen ohjelma haluaa myös lukea verkkoyhteyksiä? readia, recv:ä tms. ei saa itse kutsua (blokkaavasti) koska silloin käyttöliittymätapahtumia ei käsiteltäisi odotusaikana (eli odotus tapahtuisi muualla kuin GUI-kirjaston silmukassa) GUI-kirjastot osaavat itse odottaa verkkoyhteyksiä (tiedostoja) ja kutsua tapahtumankäsittelijää kun luettavaa tulee yhteydestä x voi lukea dataa tulee siis oma tapahtumansa tyypillisesti rajapinnasta löytyy funktio, jolle annetaan avoin verkkoyhteys (tai tiedosto) ja takaisinkutsufunktio itse asiassa (Unixissa) GUI-kirjaston tapahtumankäsittelysilmukka kutsuu yleensä itse selectiä, jossa käyttöliittymätapahtumat näkyvät erikoisina tiedostoina (X11-ikkunointijärjestelmässä välissä on oikea socket-yhteys) eli yhteenvetona selectin käyttäminen (kuten muutkin pitkäkestoiset toiminnot) pitää delegoida GUI-kirjastolle