Per Printz Madsen Linux proces og tråd programmering Per Printz Madsen Aalborg Universitet Institut for elektroniske systemer
Per Printz Madsen Overordnet Linux introduktion Multi-user og multi-process operativsystem. Soft Realtime. Skrevet i C vha. gcc. Open source. Windows system/Desktop manager GNOME og KDE. Alt hvad hjertet begærer af Compilere. Vel dokumenteret Kerne/Hardware programmering. Web-server Apache programmering fx: Perl/PHP/Python. Netværk: TCP/IP, Socket, Corba, RPC, osv.
Per Printz Madsen Filsystem /bin Her er de mest nødvendige systemkommandoer gemt. /boot Dette katalog er reserveret til systemkernen. /dev Indeholder alle device-filer. /etc Systemopsætningsfilerne. /home Brugerkonti. /lib Indeholder systemets delte filer. /opt Er reserveret til installation af valgfrie programpakker. /lost+found Genskabte filer ved fejl. /mnt Monterede filsystemer. /proc Oplysninger om de kørende programmer og Linux-kernens status. /root Systemadministratorens hjemmekatalog. /sbin Systemadministrations programmer. /tmp Midlertidige filer. /usr Delte data og programmer. /usr/local Her kan systemadministratoren installere programmer. /var Indeholder datafiler, hvis indhold ændres mens systemet er i drift.
Per Printz Madsen GNU Bourne Again Shell (bash) Opsætning af environment: Ved login læses filen ~/.bash_profile, Hver gang et terminalvindue startes læses filen ~/.bashrc. alias ll='ls -l' alias la='ls -A' PATH=.:"${PATH}" Tilføj fx følgende til.bashrc env echo $PATH
Per Printz Madsen Linux proces. En ressource enhed. Egen memory. Egen status for filer. Egen protection ID. Administrative data fx. Start tid, Forbrugt CPU-tid osv. Samt alle alm. ting, som egen stak, program status, CPU’registre, prioritet osv.
Per Printz Madsen Simpel shell #include int main (int argc, char *argv[]) { int status, pid; char kommando[80]; while (1) { printf("ppmshell>"); scanf("%s",kommando); pid = fork(); if (pid != 0) while(wait(&status) != pid); else execlp(kommando, (char *)NULL); }
Per Printz Madsen Software interrupts: Signals
Per Printz Madsen #include void slut () {printf(" -- Så er det slut\n"); exit(0);} int main (int argc, char *argv[]) { int status, pid; char kommando[80]; signal (SIGINT, slut); while (1) { printf("ppmshell>"); scanf("%s",kommando); pid = fork(); if (pid != 0) while(wait(&status) != pid); else execlp(kommando, (char *)NULL); }
Per Printz Madsen 9 Pipe fd[1] fd[0] int fd[2]; pipe(fd); // Inden fork() write(fd[1],....); // En proces. read(fd[0],....); // En anden proces.
Per Printz Madsen 10 #include int main(void) { int fd[2], nbytes; pid_t pid; char string[] = "go dav du!\n"; char readbuffer[80]; pipe(fd); pid = fork(); if(pid == 0) { close(fd[0]); // Child: Closes input side write(fd[1], string, (strlen(string)+1)); // Send "string" exit(0); } else { close(fd[1]); // Parent: Closes up output side nbytes = read(fd[0], readbuffer, sizeof(readbuffer)); //Read printf("Received string: %s", readbuffer); } Pipe
Per Printz Madsen 11 Threads
Per Printz Madsen 12 Threads systemkald. int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void), void *arg) ; Return 0 for OK ellers fejlkode. thread: Tråd ID. attr: Tråd attributter, hvis NULL så default. start_routine: Kode, der skal afvikles. arg: Evt. argumenter til koden. void pthread_exit (void *value_ptr); value_ptr: Værdi til joining tråde. Ofte NULL. int pthread_join (pthread_t thread, void **value_ptr); Return 0 for OK ellers fejlkode. Thread: Joining tråd ID. value_ptr: Værdi fra joining tråde.
Per Printz Madsen 13 Schedulering. Linux 1.Real-time FIFO. 2.Real-time Round Robin. 3.Alm. Threads. Real-Time prioriteter 0 – 99. Kun SuperUser Alm. prioriteter 100 – 139. Default 120 ( nice ) Real-Time: Statisk prioritet. Alm. Thread/Processer: Dynamisk prioritet. Tilgodeser I/O aktive over CPU aktive.
Per Printz Madsen 14 Threads systemkald. void pthread_yield(); int pthread_setschedparam(thread,schedpolicy,schedparam); void *traad(void *threadid) { // noget kode } pthread_t th; struct sched_param param; if ((rc= pthread_create(&th, NULL, traad, (void *)0))) { cout << "ERROR – code: " << rc <<'\n'; exit(-1); } param.sched_priority= sched_get_priority_min(SCHED_RR)+1; pthread_setschedparam(th, SCHED_RR, ¶m);
Per Printz Madsen 15 Process Creation
Per Printz Madsen 16 Thread Creation
Per Printz Madsen 17 Semafor, Mutex, Condition variables. Atomart system-kald, der tester, sætter og blokerer, hvis nødvendigt: Mine System V proces semaforkald: int sem_create (&semafor, key, 1 ); int sem_wait(semafor); int sem_signal(semafor); Pthread kald: int pthread_mutex_lock (mutex) int pthread_mutex_unlock (mutex) int pthread_cond_wait (condition,mutex); int pthread_cond_signal (condition);
Per Printz Madsen 18 IPC-systemkald til Unix/Linux processer: Semafor, Shared memory og Message queues. Operativsystem: Applikation:. key= ftok (".", 'a'); sem_create (&sem_id, key, 0);. sem_wait (sem_id);. key= ftok (".", 'a'); sem_get(&sem_id, key);. sem_signal (sem_id);
Per Printz Madsen 19 IPC-systemkald til Unix/Linux processer: Semafor, Shared memory og Message queues. Operativsystem: Applikation:. key= ftok (".", 'a'); sem_create (&sem_id, key, 0);. sem_wait (sem_id); key. key= ftok (".", 'a'); sem_get(&sem_id, key);. sem_signal (sem_id);
Per Printz Madsen 20 IPC-systemkald til Unix/Linux processer: Semafor, Shared memory og Message queues. Operativsystem: Applikation:. key= ftok (".", 'a'); sem_create (&sem_id, key, 0);. sem_wait (sem_id); keysem_id. key= ftok (".", 'a'); sem_get(&sem_id, key);. sem_signal (sem_id);
Per Printz Madsen 21 IPC-systemkald til Unix/Linux processer: Semafor, Shared memory og Message queues. Operativsystem: Applikation:. key= ftok (".", 'a'); sem_create (&sem_id, key, 0);. sem_wait (sem_id); keysem_id. key= ftok (".", 'a'); sem_get(&sem_id, key);. sem_signal (sem_id);
Per Printz Madsen 22 IPC-systemkald til Unix/Linux processer: Semafor, Shared memory og Message queues. Operativsystem: Applikation:. key= ftok (".", 'a'); sem_create (&sem_id, key, 0);. sem_wait (sem_id); keysem_id. key= ftok (".", 'a'); sem_get(&sem_id, key);. sem_signal (sem_id);
Per Printz Madsen 23 IPC-systemkald til Unix/Linux processer: Semafor, Shared memory og Message queues. Operativsystem: Applikation:. key= ftok (".", 'a'); sem_create (&sem_id, key, 0);. sem_wait (sem_id); keysem_id. key= ftok (".", 'a'); sem_get(&sem_id, key);. sem_signal (sem_id);
Per Printz Madsen 24 IPC-systemkald til Unix/Linux processer: Semafor, Shared memory og Message queues. Operativsystem: Applikation:. key= ftok (".", 'a'); sem_create (&sem_id, key, 0);. sem_wait (sem_id); keysem_id. key= ftok (".", 'a'); sem_get(&sem_id, key);. sem_signal (sem_id);
Per Printz Madsen 25 IPC-systemkald til Unix/Linux processer: Semafor, Shared memory og Message queues. Operativsystem: Applikation:. key= ftok (".", 'a'); sem_create (&sem_id, key, 0);. sem_wait (sem_id); keysem_id. key= ftok (".", 'a'); sem_get(&sem_id, key);. sem_signal (sem_id);
Per Printz Madsen 26 Klassiske IPC-typer. Pipe Named pipes eller FIFO’s Message Gueues Shared memory
Per Printz Madsen 27 Named pipes eller FIFO’s. Named pipes eksisterer som en device fil i filsystemet. Processer med forskellige forældre kan udveksle data gennem named pipe. Når processer er færdige med at udveksle data forbliver named pipes i filsystemet. mkfifo minfifo Device fil kaldt minfifo fp = fopen(”minfifo”, ”r”); fgets(readbuf, 80, fp); fp = fopen(”minfifo”, ”w”); fputs(”go dav do”, fp);
Per Printz Madsen 28 Message Gueues. En FIFO kø der oprettes i operativsystemet vha en key. Operativsystem: Applikation:. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0);. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. qbuf->mtype = type; msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0);
Per Printz Madsen 29 Message Gueues. Operativsystem: Applikation:. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0); key. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. qbuf->mtype = type; msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0);
Per Printz Madsen 30 Message Gueues. Operativsystem: Applikation:. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0); key. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. qbuf->mtype = type; msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0); kø
Per Printz Madsen 31 Message Gueues. Operativsystem: Applikation:. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0); key. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. qbuf->mtype = type; msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0); kø qbuf
Per Printz Madsen 32 Message Gueues. Operativsystem: Applikation:. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0); key. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0); kø qbuf
Per Printz Madsen 33 Message Gueues.. key= ftok (".", 'a'); qid = msgget(key, IPC_CREAT|0660);. msgsnd(qid, (struct msgbuf *)qbuf, strlen(qbuf->mtext)+1, 0); struct msgbuf { long mtype; /* type of message */ char mtext[1]; /* message text */ }; Datatype. Modtager adresse.....
Per Printz Madsen 34 Shared memory. Delt memory mellem flere processer. Den hurtigste form for IPC. Men husk mutual exclusion. Operativsystem: Applikation: key= ftok (".", 'a'); char *mem; if ((shmid = shmget(key, size, IPC_CREAT|IPC_EXCL|0666))==-1){ error; } mem= shmat (shmid, 0, 0);. key= ftok (".", 'a'); char *mem; if ((shmid = shmget (key, size, 0)) == -1) { error; } mem= shmat (shmid, 0, 0); shm
Per Printz Madsen 35 Real-time synkronisering af processer og tråde. 1. Signaler fra Realtime uret (SIGALRM) Op til Hz 2. Brug af Sleep Fx nanosleep() og clock_gettime(); og til Hz eller mere.
Per Printz Madsen Multi-proces eksempel. P1P2P3Moderen Sem1 Sem2 signalwait signalwait Realtidsur void sampel_pc(); Sem3 signal wait
Per Printz Madsen Håndtering af hardware Device drivere.
Per Printz Madsen 38 Device-Independent. Protections. Major nr: x Minor nr: y /dev/MinDriver Min driver ttys Protections. Major nr: 3 Minor nr: 48 /dev/ttys0 Protections. Major nr: 3 Minor nr: 49 /dev/ttys1 fd= open(”/dev/MinDriver”,..); read(fd,..); write(fd,..); Nr: x Nr: 3 Operativsystem Applikation
Per Printz Madsen 39 Device-Independent. mknod –m 664 MinDevice c Oprettelse af device fil: Character devices: 1 mem 2 pty 3 ttyp 4 ttyS 6 lp 7 vcs 10 misc 13 input 14 sound 21 sg 180 usb /proc/devicesMajor numre: 60 to 63, 120 to 127, 240 to 253 er reserveret for eksperimentelt brug.
Per Printz Madsen 40 Loadable kernemoduler. #include void init_module(void) {} void cleanup_module(void) {} make mod1.ko insmod mod1.ko APP OPS rmmod mod1
Per Printz Madsen 41 Hjemmelavet device driver 1.Skriv et kernemodul, der implementerer devicen. Major= register_chrdev(0,”MinDriver”,&fops); Plus meget mere. 2.Indsæt modul i kernen. insmod MinDriver.ko 3.Lav en devicefil mknod –m 664 MinDevice c Major 7
Per Printz Madsen 42 Hjemmelavet device driver static struct file_operations fops = {.read = dev_read,.write = dev_write,.open = dev_open,.release = dev_release }; int init_module(void) { Major = register_chrdev(0, ”MinDriver”, &fops); if (Major < 0) { printk("Registering the character device failed with %d\n", Major); return Major; } printk("I was assigned major number %d\n", Major); return 0; } void cleanup_module(void) { int ret = unregister_chrdev(Major, ”MinDriver”); if (ret < 0) printk("Error in unregister_chrdev: %d\n", ret); }
Per Printz Madsen 43 Hjemmelavet devicedriver static struct file_operations fops = {.read = dev_read,.write = dev_write,.open = dev_open,.release = dev_release }; static ssize_t dev_read(struct file *filp, char *buf, size_t len, loff_t * off) { if (copy_to_user(buf, buffer, Size)) return -EFAULT; return bytes_read; } static ssize_t dev_write(struct file *filp, const char *buf, size_t len, loff_t * off) { if (copy_from_user(buffer, buf, len)) return -EFAULT; return 0; }
Per Printz Madsen 44 make - Makefile CXXFLAGS = -O2 -Wall LFLAGS= -lrt OBJ= src1.o src2.o eks1: $(OBJ) g++ -o eks1 -lrt $(OBJ) src1.o: src1.cpp src2.h src2.o: src2.cpp clean: rm *.o eks1 Makefile src1.cpp src2.cpp src2.h
Per Printz Madsen 45 Automake Genererer en systemafhængig Makefile med alle nødvendige funktioner. Test af målsystemet. Installation af pakken. Generering af distribuerbar tar arkiv. Osv.
Per Printz Madsen 46 Automake Opret: configure.in Makefile.am ## Filnavn: Makefile.am AUTOMAKE_OPTIONS = foreign bin_PROGRAMS = eks1 eks1_SOURCES = src1.cpp src2.cpp src2.h #Filnavn: configure.in AC_INIT(src1.cpp) AM_INIT_AUTOMAKE( demo-eks, 1.0 ) AC_PROG_CXX AC_STDC_HEADERS CXXFLAGS="-O2 -Wall" LDFLAGS="-lpthread -lrt -lm" AC_OUTPUT(Makefile)
Per Printz Madsen 47 Automake aclocal automake -a autoconf./configure make make install make dist make clean
Per Printz Madsen C++ / my first program in C++ #include using namespace std; int main () { double a= 4.5; cout << "godav! a= " << a << endl; cin >> a; cout << "a er nu: " << a << endl; return 0; }
Per Printz Madsen Classediagram Bil Farve : string Årgang : int motor: Motor Start() Tank op() Navn Attributter Operationer Personbil Type: string Lastbil Nettolast : int Motor Effekt: float AntCyl: int SætGSpjæld( )... 1 UML
Per Printz Madsen C++ class Bil{ string farve; int aargang; public: void start(); void tankop(float liter); Bil(string,int); }; Bil::Bil(string fa,int aar) { farve= fa; aargang= aar; } class Personbil: public Bil{ string type; public: Personbil(string f, int a): Bil(f,a){}; Personbil(void): Bil("blaa",1900){}; };
Per Printz Madsen C++ Personbil kadet("gul",1986); Personbil *fiatPtr= new Personbil("blaa",1965); Personbil *fordPtr= new Personbil; int *intarray = new int[10]; Personbil *bilpark= new Personbil[10];
Per Printz Madsen C++ Exception handling L ow-level kode detekterer fejl High-level kode håndterer fejl. Metode try og catch try { int* myarray= new int[1000]; } catch (exception& e){ cout << "Std. exception: " << e.what() << endl; }