Aiheita luentojen osaan 1 ######################### Tiedon siirtoa -------------- Ohjelma saa kaksi parametria, kaksi tiedostonimeä (tdsto1, tdsto2). Ohjelma käynnistää lapsi-prosessin, joka avaa ensimmäisenä parametrina annetun tekstitiedoston (tdsto1). Lapsi lukee tämän jälkeen tiedostosta ja välittää tiedoston sisällön äidilleen, joka kirjoittaa tiedon toisena parametrina (tdsto2) saatuun tiedostoon. Siirrä tieto morsettamalla siten, että lapsi lähettää Morsen aakkosina koodatun merkin signaalina äidilleen. Voit esimerkiksi määritellä, että USR1-signaali on ns. "lyhyt" ja USR2-signaali on "pitkä". Miten erottelet yksittäiset merkit ja jopa sanat? Morsen aakkoset löytyvät esim. tuolta: http://aimo.kareltek.fi/~reni/morse.php http://morsecode.scphillips.com/morse.html Virhetilanteeseen on oma Morsen aakkonen. Huomioi, että rivinvaihto puuttuu - keksi tälle oma versiosi. Jos tdsto1 ei ole olemassa, äiti-prosessin pitää saada tästä tieto lapseltaan. Mahdollisia toteutusvaihtoehtoja - pidetään taukoja merkkien välissä. Kuluneen ajan saa selville esim. "gettimeofday" funktiota käyttäen. - käytetään muita signaaleja lisäksi. Ainakin SIGALARM ja SIGINT voisivat tulla kysymykseen. Tällöin Ctrl-C:n painaminen ei lopettaisi ohjelmaa, mutta se ei haittaa tässä tapauksessa. Ohjelmakoodin "siistimistä" -------------------------- Tee ohjelma, jolle annetaan parametreina tiedostojen nimiä. Ohjelma käynnistää lapriprosesssin kutakin tiedostoa kohden. Lapset poistavat tiedostoista kaikki tyhjä rivit ja kommenttirivit, ja kirjoittavat "siistityn" koodin uuteen tiedostoon, jonka nimi on "alkuperäinennimi.siisti". Kommenttirivi voi olla sellainen - joka alkaa merkeillä "//" ja päättyy rivin vaihtoon (luonnollisesti) - tai sellainen, joka alkaa "/*" merkeillä ja päättyy vastaavasti "*/" merkkeihin. Äiti odottaa lapsiprosessiensa päättymistä ennen kuin itse poistuu. Hieman monimutkaisempi "Hello World" ------------------------------------ Tee mahdollisimman monimutkainen versio klassisesti "Hello World"-sovelluksesta, joka siis perinteisesti tulostaa ruudulle, tms. ikkunaan, "Hello World", ja poistuu. Ohjelma voi esimerkiksi lukea tiedostojärjestelmästä jonkin arvon, jonka perusteella luo lapsi-prosesseja, jotka sitten esim. signaalien avulla käsketään kukin kirjoittamaan yksi merkki ruudulle ja poistumaan. Mitä tahansa voi tähän suunnitella, kunhan ohjelma täyttää HT:n ehdot, eli siinä käytetään lukuisia eri toimintoja lopputuloksen aikaansaamiseksi. Tehokkuuden vertailua --------------------- Vertaile muistiinkuvatun tiedoston ja tavallisen I/O:n suorituskykyä. Tee ohjelma, joka avaa tiedoston, hakee tiedostosta jotain merkkijonoa, korvaa sen toisella merkkijonolla ja kirjoittaa takaisin. Tee kaksi ohjelmaa, joista toinen käsittelee tiedostoa tavallisella I/O:lla ja toinen käyttää muistiinkuvattuja tiedostoja, sekä lukemiseen että kirjoittamiseen. Miten luet ja kirjoitat tiedostoja? Merkki, rivi vai jopa tiedosto kerrallaan? Mitä eroa noilla voisi olla? Miksi? Vertaile ohjelmia muistinkäytön ja suoritusajan (seinäkello ja prosessoriaika) suhteen. Testiä varten luo itse (tai kaiva jostain ) riittävän suuri tiedosto, jotta pääset vertailemaan eroja. Tehtävässä pitää myös huomioida, että Linux käsittelee tiedostoja toisinaan hieman "optimoiden"... miten? Tämän harjoitustyön oppimispäiväkirjan pitää sisältää kuvaus tehdyistä vertailuista ja mitä selvisi. Aiheita luentojen osaan 2 ######################### Tulostuksen kaappaaja --------------------- Tee kirjasto, jonka avulla vanhojen ohjelmien tavalliset tulostukset (esim. printf()) ohjautuvatkin erillisille tulostusprosessille tai -säikeelle. Tämä prosessi vuorostaan käsittelee tulostukset edelleen, esimerkiksi kirjoittaa tulostukset lokiin. Muukin toiminta on mahdollista, esimerkiksi lähettää ne verkon välityksellä toiselle koneella (ei kuulu kurssin aiheisiin, ei tarvitse toteuttaa). Periaatteessa toiminta on sama, kuin jos antaisi komennon "ohjelma > loki.txt". Toteutuksen pitää olla mahdollisimman yksinkertaisesti lisättävissä vanhojen ohjelmien lähdekoodiin, ja sen pitää tukea myös näiden ohjelmien mahdollisesti synnyttämiä lapsiprosesseja tai säikeitä (rinnakkaisia kirjoittajia). Loki-tiedoston nimi pitää olla määritettävissä vanhassa ohjelmassa, ja, jos tiedosto on olemassa, uudet viestit lisätään perään. stderr-virtaa ei pidä kaapata, vaan sen toimintaan ei pidä vaikuttaa. Vihje: idea on siis ohjata stdout-virta ohjelman sisällä jotenkin "sopivasti". Tee myös ohjelma, jolla testaat kirjaston toimintaa, ja jolla osoitat, että kirjastosi toimii sekä lapsiprosesseilla että säikeillä. Tiedon siirtoa -------------- Hieman vastaava tehtävä kuin Morsetus signaaleilla. Tee kaksi ohjelmaa. Ohjelma A voidaan käynnistää useampaan kertaan, useammaksi prosessiksi. Kukin avaa oman parametrina annetun tekstitiedoston (tdsto1) ja lukee tämän jälkeen tiedostosta ja välittää tiedoston sisällön ohjelmalle B (daemon), joka kirjoittaa kukin lähettämät tiedot uusiin tiedostoihin. Tieto pitää pystyä siirtämään vähintään kahdella eri menetelmällä, jotta ohjelmasi toimisi mahdollisimman monella alustalla (valitse itse, miten tämän valinta tehdään). Siirrä tieto a) FIFO-putkilla b) viesteillä tai c) jaetun muistin kautta. Ohjelma B on koko touhun koordinaattori, ja antaa tarvittaessa vuorotellen kirjoituslupia eri kirjoittajille. Kirjoitusten pitää voidaa tapahtua rinnakkain, ei siten, että ensin kirjoittaa ensimmäinen pyytäjä, sitten toinen, jne. Luvan saadessaan, kirjoittaja saa kirjoittaa siis tietyn määrän kerrallaan putkeen. Millä eri tavoilla tämä synkronointi voidaan saada aikaan? Voit olettaa, että kirjoittajia voi olla korkeintaan 256. Oma syslog-daemon ----------------- Tee syslog-daemonia vastaava oma toteutus, ja siihen kuuluva kirjasto. Toiminta pitää olla sellainen, että daemon odottelee lokitiedostoon kirjoitettavia viestejä jostain putkesta. Omiin ohjelmiin käännetään mukaan toteuttamasi kirjasto, joka sisältää funktion, jolla näitä lokiviestejä voi daemonille lähettää. Daemon lisää lokiviestehin päivämäärän ja kellonajan millisekunnin tarkkuudella. Ohjelman, joka viestejä haluaa lähettää ei pidä tietää mitään daemonin toteutuksesta tai edes putkista - kirjasto piilottaa tämän ohjelmalta. Toteutuksen pitää kyetä tukemaan useampia kirjoittajia oikein (huom. tämä VAATII erityistoimenpiteitä, tee "stressitesti" daemonillesi ja katso toimiiko daemon oikein). Lisäksi eri kirjoittajien viestit pitää eritellä, esimerkiksi, kaksi eri asiakkaan lähettämään samanlaista lokiviestiä pitää pystyä erottamaan toisistaan. Lokiviesti on muodoltaan siis jotain tuon suuntaista: PVM KELLO KUKA VIESTI esimerkiksi: Dec 24 12:00:01.250 asiakkaannimi_ja/tai_pid Tämä on viestini Viestit pitää pystyä välittämään vähintään kahdella eri menetelmällä. Valitse itse, miten temppu tehdään asiakkaan päässä, daemonin pitää pystyä tukemaan kahta menetelmää samanaikaisesti. Siirrä tieto a) FIFO-putkilla b) viesteillä tai c) jaetun muistin kautta. Omat aio-funktiot ----------------- Toteuta luentojen toisessa osassa esitellyt asynkroniseen tiedonsiirtoon tarkoitetut aio-funktiot itse. Tee oma kirjasto, josta löytyy vastaavat kutsut ja ne toteuttavat saman toiminnallisuuden kuin luennolla esitellyt funktiot. Tarkoitus ei ole siis tehdä omia funktioita, jotka ennen pitkää kutsuvat standardeja aio-funktioita, vaan nimenomaan tehdä omat toteutus. Funktiokutsua lio_listio ei tarvitse toteuttaa. Tehtävään kuuluu luonnollisesti myös testiohjelma, jolla voit testata kirjastoasi. Haastavaa on mm. testiohjelman ja kirjaston toiminnan synkronointi, ja yhteisen muistin järjestäminen ja käyttö. SäiePankki-sovellus ----------------- Tee sovellus, joka toteuttaa karkean pankkitoiminnallisuuden. Pankki sisältää N kappaletta palvelutiskejä (säädettävissä komentoriviltä), jokainen omassa säikeessään. Jokainen säie odottaa viestejä omassa viestijonossaan. Asiakas valitsee jaetussa muistissa olevien viestijonojen asiakasmäärien perusteella lyhimmän jonon, jonka avulla alkaa joko odottamaan vuoroaan (edellinen asiakas on vielä kesken) tai alkaa kommunikoimaan viestijonon välityksellä pankkipalvelijan kanssa yksi palvelupyyntö kerrallaan. Itse tilit on kaikki yhdessä ja samassa tiedostossa, ja niiden yhteiskäyttö on toteutettu R/W lukkojen avulla Kaikki pankkipalvelimet ylläpitävät myös yhtä yhteistä pankin omaa saldoa, joka kuvaa tämänhetkistä rahamäärää pankissa (siis kaikkien tilien saldot yhteenlaskettuna). Tämän lisäksi on olemassa säie pomo, joka aina tietyn aikavälein kysyy jokaiselta pankkipalvelijalta hänen omaa saldoaan eli kuinka paljon hän on tallettanut pankkiin ja kuinka paljon antanut ulospäin. Pomosäie saa ohittaa kaikki jonossa olevat asiakkaat, mutta ei keskeytä käsittelyssä olevaa palvelupyyntöä. Tämän osuuden kaikkien palvelinsäikeiden pitää tehdä ennenkuin yksikään palvelija saa jatkaa asiakkaiden palvelemista. Asiakkaat voivat esimerkiksi lähettää komentoja: "l 1": anna tilin 1 tilitiedot "n 1 123": nosta tililtä 1 rahaa 123 euroa "s 1 2 123": siirrä tililtä 1 tilille 2 yhteensä 123 euroa "t 1 234": talleta tilille 1 rahaa 234 euroa. Komennot annetaan joltain sopivalta kehotteelta, ts. asiakasohjelma lukee käskyjä käyttäjältä ja välittää ne pankkipalvelijalle. Tilitiedot tarkoittavat tässä tilin saldoa. Haasteellisempi työ olisi lisäty myös ns. tiliote, ts. pankkisovellukselta voisi myös kysyä tilitapahtumia. Tämä toiminnallisuus ei ole ehdoton vaatimus työn hyväksymiselle eikä ole ehto täysien pisteiden saamiselle. Tehokkuusvertailu ----------------- Tämä työ on haastava. Tarkoituksena on vertailla prosessien ja säikeiden välistä eroa tehokkuuden kannalta. Tehtävässä on tarkoitus mitata kuinka kauan aikaa kuluu seuraaviin asioihin: - Prosessin luonti vs Säikeen luonti (aika ja tarvittava keskusmuisti) - Prosessin vaihto vs Säikeen vaihto - Kokotesti: Semaforin koko vs Mutexin koko - Semaforin saantiaika vs mutexin saantiaika (kun tyhjiä) - Semaforin saantiaika vs mutexin saantiaika kun yksi prosessi/säie jo pitää kyseistä oliota ja sitten vapauttaa sen. - Käytännön testi: usean tiedoston kopiointi (valitse ISO tiedosto) prosesseilla / säikeillä - Käytännön testi: tiedoston siirto prosessien välillä/ säikeiden välillä käyttäen: 1) putkia 2) viestijonoja 3) jaettua muistia