11. Tosiaikaohjelmointia Linux:lla
Linux ei ole varsinainen tosiaikakäyttöjärjestelmä. Tästä huolimatta Linux:a voi hyvin käyttää pehmeissä (soft) tai tiukissa (firm) tosiaikajärjestelmissä käyttöjärjestelmänä.
Tässä osuudessa käydään läpi niitä toimia, joita ohjelmassa kannattaa tehdä, jotta ohjelma toimisi paremmin tosiaikaympäristössä. Kaikkissä esimerkeissä oletetaan että käytössä on Linux:n ydin 2.4.x ja ytimeen on asennettu low latency patch. Lisäksi oletetaan että käytössä on root-tunnus.
Aluksi kannattaa estää sivuttajaa poistamasta ohjelmaa muistista, eli lukita koko prosessin muistiavaruus keskusmuistiin. Tämä tapahtuu funktiolla mlockall (katso man mlockall). Varatun muistin voi palauttaa sivuttajan käytöön funktiolla munlockall (katso man munlockall).
Esimerkiksi:
#include < sys/mman.h > #include < unistd.h > #include < stdio.h > #include < stdlib.h > int main(int argc,char **argv) { if ( (mlockall(MCL_FUTURE)) < 0 ) { perror("mlockall"); exit(1); } /* Toimintaa */ if ( ( munlockall() ) < 0 ) { perror("munlockall"); exit(1); } exit(0); }
Toiseksi, kannattaa ottaa käyttöön tosiaikaskeduleri. Käytännössä tämä tapahtuu muuttamalla Linux:n oletusskeduleri toiseksi ja antamalla prosessille prioriteetti (katso man sched_setscheduler ). Esimerkiksi:
#include < sys/types.h > #include < sys/time.h > #include < sys/mman.h > #include < stdio.h > #include < stdlib.h > #include < sched.h > int main(int argc, char **argv) { /* Alkutoimet ... */ struct sched_param scparam; memset(&scparam,0,sizeof(struct sched_param)); scparam.sched_priority = 10; sched_setscheduler(0,SCHED_RR,&scparam); /* Tosiaikaprosessin toimintaa... */ }
Tosiaikaprosessien väliseen kommunikointiin kannattaa käyttää mahdollisimman nopeata menetelmää (esim jaettua muistia). Jos tietoliikennettä välttämättä tarvitaan, kannattaa käyttää UDP-protokollaa. Jos tietoliikenteen luotettavuus on välttämätöntä ja TCP-protokolla välttämätön, kannattaa asettaa Nagle-algoritmi pois päältä (katso man tcp) funktiolla setsockopt() (katso man setsockopt). Esimerkiksi:
#include < sys/types.h > #include < sys/socket.h > int main(int argc,char ** argv) { int socketfd; int optval = 1; /* Alkutoimet ... */ if( ( setsockopt(socketfd, SOL_TCP, TCP_NODELAY,(void *)&optval, sizeof(int) ) ) < 0 ) { perror("setsockopt"); exit(1); } /* Kommunikointia...*/ }
Jan Lindström (Jan.Lindstrom@cs.Helsinki.FI)