1.1. Les processus Un processus est un programme qui sexcute et qui possde son compteur ordinal, ses registres et ses variables. Conceptuellement, chaque processus a son propre processeur virtuel. En ralit, le vrai processeur commute entre plusieurs processus. Cette commutation rapide sappelle multiprogrammation. 1.1.1. Hirarchie entre les processus Les systmes dexploitation qui font appel au concept de processus doivent permettre de crer les processus requis. Dans la plupart des systmes, il faut pouvoir crer et dtruire dynamiquement les processus. En Unix, un processus particulier init est lanc au dmarrage de la machine. Il cre un processus par terminal, lorsque la connexion est valide, il lance un nouveau processus charg de lire et dinterprter les commandes de lutilisateur (Shell). Chacune de ces commandes peut elle-mme crer un nouveau processus et ainsi de suite. Notez quun processus na quun seul pre mais peut avoir plusieurs fils. Tous les processus du systme font donc partie dun seul arbre dont la racine est init. 1.1.2. Les diffrents tats dun processus Les processus, bien qutant des entits indpendantes, doivent parfois interagir avec dautres processus. Les rsultats dun processus peuvent, par exemple, tre les donnes dun autre. Exemple : ls l | more
Les tats possibles dun processus sont les suivants : 1. Elu : en cours dexcution. Un processus lu peut tre arrt, mme sil peut poursuivre son excution, si le SE dcide dallouer le processeur un autre processus 2. Bloqu : attend un vnement extrieur pour pouvoir continuer, par exemple une ressource, lorsque la ressource est disponible, il passe ltat prt 3. prt : suspendu provisoirement pour permettre lexcution dun autre processus Quatre transitions peuvent avoir lieu entre ces diffrents tats :
Elu Bloqu Prt 2 1 3 4 Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 2 1 : Le processus se bloque en attente de donnes 2 : Lordonnanceur choisit un autre processus 3 : Lordonnanceur choisit ce processus 4 : Les donnes deviennent disponibles
Le modle des processus permet de mieux comprendre ce qui se passe lintrieur du systme. Une partie des processus excutent les programmes qui traitent les commandes tapes par les utilisateurs. Les autres processus font partie du systme et grent les tches telles que les requtes au gestionnaire de fichiers ou les oprations sur les disques. Ces processus se bloquent lorsquils attendent un vnement. La couche la plus basse dun SE est lordonnanceur (scheduler). Il est surmont par une multitude de processus. La gestion des interruptions, la suspension et la relance des processus sont reportes dans lordonnanceur.
1.1.3. Les processus en UNIX La commande ps liste, avec plus ou moins de dtails, tous les processus ou seulement ceux de lutilisateur, suivant diffrentes options. Ainsi : ps fH uetudiant1 prsente les champs :
UID Nom du propritaire du processus PID Numro du processus PPID Numro du processus pre STIME Heure de lancement du processus TTY Le terminal ou la fentre du processus CMD La commande qui a permis de lancer le processus ps e : affiche tous les processus de tous les utilisateurs Exemple : ps fH uetudiant
Prof. C.EL AMRANI Programmation systme sous UNIX 3 La hirarchie des processus est reprsente par larbre suivante :
Le processus 1 (init) est le pre des processus 533 et 531 correspondant des fentres X Window. 1.2. Les appels systme (processus) 1.2.1. Caractristiques dun processus
Les appels systmes :
int getpid () fournit le numro du processus en cours dexcution int getppid () fournit le numro du pre du processus
Un utilisateur non propritaire dun programme excutable peut obtenir, le temps de lexcution du programme, lidentit du propritaire du programme de faon bnficier des droits daccs du propritaire. Pour cela, le propritaire doit positionner un droit s au lieu du x pour les droits daccs du programme Lors de lexcution, il y a un utilisateur rel (uid) et un utilisateur effectif (euid). La mme possibilit existe pour les groupes, un utilisateur peut prendre le groupe du propritaire du fichier, le temps de lexcution du programme. Il y a donc un groupe rel (gid) et un groupe effectif (egid). Les appels systmes correspondant sont :
int getuid () fournit le numro du propritaire rel int geteuid () fournit le numro du propritaire effectif int getgid () fournit le numro du groupe rel int getegid () fournit le numro du groupe effectif
Exemple ; 1 533 (xemacs) 531 (konsole) 535 (/bin/bash) 602 (more) Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 4 Lexcutable /usr/bin/passwd, dont root est propritaire, a un droit daccs s (-r-s--x--x). Les utilisateurs de /usr/bin/passwd acquirent, le temps de lexcution du programme, les droits daccs root sur /etc/passwd (-rw-r--r--). 1.2.2. Lappel systme pipe Un fichier est constitu de plusieurs descripteurs. Un descripteur est un entier compris entre 0 et 255 pour Linux. 0, 1 et 2 sont rservs pour lentre, la sortie standard la sortie en cas derreurs. (3 pour la sortie dun tube, 4 pour lentre dun tube)
Un tube de communication est un tuyau dans lequel un processus crit des donnes quun autre processus peut lire. Lappel systme pipe () cre un tube anonyme et fournit un double descripteurs utilis pour lire ou crire dans le tube : int pipe (int descripteur [2]) dclar dans <unistd.h> Le tube est entirement sous le contrle du noyau et rside en mmoire. Le processus reoit les deux descripteurs correspondant lentre et la sortie du tube. Le descripteur dindice 0 est la sortie du tube, il est ouvert en lecture seule. Le descripteur 1 est lentre, ouverte en criture seule. En effet, les tubes sont des systmes de communication unidirectionnels.
Tube de communication #include<stdio.h> #include<unistd.h> // pour certaines distributions de Linux, exit() est dfinit dans main() // <stdlib.h>, il faudrait donc rajouter cette bibliothque pour que { // a fonctionne int tube[2]; unsigned char buffer[256]; int i;
printf("creation du tube\n"); if(pipe(tube)!=0) { perror("pipe"); exit(1); NOYAU Ente Sortie Processus read() write()
Processus 0 2 tube[1] tube[0] 1 Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 5 } for (i=0;i<256;i++) buffer[i]=i; printf("ecriture dans le tube\n"); if(write(tube[1],buffer,256)!=256) { perror("ecriture"); exit(1); } printf("lecture depuis le tube\n"); if(read(tube[0],buffer,256)!=256) { perror("lecture"); exit(1); } printf("tube[0]: %d\n",tube[0]); /* =3 (descripteur 3 du processus), lecture, sortie du tube */ printf("tube[1]: %d\n",tube[1]); /* =4 (descripteur 4 du processus), criture, entre du tube */ } les descripteurs pointent vers les inodes du tube. La cration dun tube pour un seul processus ne prsente aucun intrt. On utilise ce mcanisme pour faire communiquer deux processus (ou plus), en invoquant les appels systmes exec et fork.
Tube du pre vers le fils 1.2.3. Lappel systme execve et les fonctions de la famille exec Lappel systme execve() excute un programme excutable ou un script shell. La syntaxe est la suivante : int execve (const char* filename, char* const argv[ ], char* const envp[ ]) ;
filename Nom ou chemin du fichier excuter argv Tableau contenant les arguments du programme envp Tableau contenant les variables denvironnement
Rappel : Rappel sur main : main (int argc, char* argv[ ], char* envp [ ])
0 1 2 3 tube[0] 4 tube[1] Pre Fils tube[1] tube[0] Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 6 le pre argc Nombre de paramtres sur la ligne de commande (c : counter) argv Pointeur vers un tableau de pointeurs qui dsignent des donnes de type char (v : vector) envp Pointeur vers un tableau de pointeurs qui dsignent les variables denvironnement (p : pointer) Rappel sur un pointeur avec indice : Soit: char *pt; On a: pt[ i ] = *(pt+i) avec pt=&t[k] par exemple Et donc pt[ i ] est de type char
Il existe 5 variantes de execve () Les paramtres sont donnes dans une liste (do l), termine par NULL :
int execl (const char* filename, char* const arg, ) ;
int execlp (const char* filename, char* const argv, ) ; p indique que lexcutable doit tre cherch en utilisant la variable PATH
int execle (const char* filename, char* const argv, , char* const envp[ ]) ; e indique que le tableau des variables denvironnement suit la liste des paramtres
int execv (const char* filename, char* const argv[ ]) ; v indique que les paramtres sont dans un tableau (v : vector) int execvp (const char* filename, char* const argv[ ]) ;
Exemple : /* execls.c */ #include<stdio.h> #include<unistd.h> main() { execlp("ls","ls",NULL); perror("erreur sur execlp"); } Lexcution donne le listing des fichiers/rpertoires du rpertoire courant. 1.2.4. Lappel systme fork de cration de processus Lappel systme fork () (de <unistd.h>) cre un processus fils qui diffre de son pre uniquement par son numro de PID et PPID. Fork() fournit 0 pour le fils. La syntaxe est : pid_t fork(void)
fork() exit(0) le fils =0 !=0 Chapitre 1. Les appels systme pour les processus
Rq : si linstruction sleep(5) est prise en compte :
processus pere: PID = 2033 , PPID = 1924 autres commandes processus fils: PID = 2034 , PPID = 1 le processus fils est adopt par le processus initial init de PID = 1, car le pre se termine avant le fils 1.2.5. Autres appels systme sur les processus lappel systme wait bloque un processus en attente de la fin de lexcution dun fils quil a cr. La syntaxe est : pid_t wait (int * status) ; la fonction retourne le PID du fils qui vient de se terminer. Status, sil est non NULL, reoit des informations sur la faon dont sest termine le processus (valeur du exit du fils). Il existe aussi lappel systme : waitpid qui permet dattendre la fin dun fils particulier.
Lappel systme _exit termine le processus courant. Sil reste des fils non termins, ceux-ci reoivent le processus 1 pour pre. Sa syntaxe : void _exit (int status) ; La fonction exit ralise lappel systme _exit : void exit (int status) ;
La fonction sleep () suspend un processus pendant le nombre de secondes indiqu en paramtre. Sa syntaxe : unsigned int sleep (unsigned int seconds) ; Si la fonction est interrompue (par un signal) elle fournit le nombre de secondes restant avant la fin programme, 0 sinon. Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 8 le pre wait attendre la fin du 1 er fils wait attendre la fin du 2 me fils 1.3. Utilisation de fork, exec, pipe, dup2 1.3.1. Excution de deux processus squentiels indpendants Pour excuter les deux commandes : pwd et ls -li linterprteur de commandes (bash) doit crer un processus, lui faire excuter pwd et attendre la fin du processus fils. Il peut alors crer un nouveau processus et lui faire excuter la commande ls -l
Le programme en C fork1.c est le suivant :
#include<stdio.h> #include<unistd.h> #include<wait.h> main() { if(fork()==0) { printf("execution de pwd\n"); execlp("pwd","pwd",NULL); perror ("Pb pwd"); exit(1); } wait(0); if(fork()==0) { printf("execution de ls -l\n"); execlp("ls","ls","-l",NULL); fork() exit(1) en cas derreur Le 1 fils excute pwd et se termine =0 !=0 fork() exit(1) en cas derreur Le 2 fils excute ls -l et se termine =0 !=0 Cration de 2 processus squentiels indpendants Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 9 perror("Pb ls -li"); exit(1); } wait(0); } Excution : $ ./fork2 $ execution de pwd $ /home/compte6/syst $ execution de ls -l total 88 62662 -rwxr--r-- 1 compte6 groupe2 14 avr 11 15:33 c 62658 -rwxr-xr-x 1 compte6 groupe2 11795 avr 11 16:52 execls
1.3.2. Redirection des entres et des sorties sur un fichier
Filtres en C Un filtre Unix lit les donnes sur son entre standard, les modifie et les envoie sur sa sortie standard. Les entres et sorties standards peuvent tre rediriges vers un fichier ou un tube. Les messages derreurs doivent tre crits sur la sortie derreur (N 2, stderr au niveau de la bibliothque standard, pour les filtres en C)
Exemples :
soit le filtre majuscul : majuscul.c #include<stdio.h> #include<ctype.h> /* toupper */ main() { int c; while((c=getchar())!=EOF) putchar(toupper(c)); } excution : (soit un fichier de texte essai1.txt : bonjour) $ ./majuscul < essai1.txt (dans essai1.txt : bonjour) BONJOUR
soit le filtre par : par.c #include<stdio.h> #include<stdlib.h> main(int argc, char* argv[]) 2 0
filtre 1 Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 10 { int largeur=10; /*par defaut*/ int n=0; /*nombre de caracteres*/ char c;
if (argc==2)largeur= atoi(argv[1]); while((c=getchar()) != EOF) { if(c=='\n')c=' '; putchar(c); if(++n >= largeur) { putchar('\n'); n=0; } } putchar('\n'); } excution : (soit un fichier de texte essai2.txt : bonjour monsieur) $ ./par 4 < essai2.txt bonj our mons ieur
Voici un programme en shell bash qui excute ces deux programmes, et communique les informations de sortie du premier, en entre du second : majparsh #!/bin/sh if [ $# -ne 1 ]; then echo "preciser le fichier a traiter" exit 1 fi
Prof. C.EL AMRANI Programmation systme sous UNIX 11 fils 0 1 2 fe fm fils Il est possible de crer un programme C qui effectue la mme fonction. Il faut rediriger lentre et la sortie du premier fils (excutant majuscul) et lentre standard du second fils (excutant par).
Ouverture dun fichier int open (const char* pathname, int flags, mode_t mode) (voir : man open)
pathname nom du fichier ouvrir flags options dans louverture du fichier : O_RDONLY ouverture en lecture O_WRONLY ouverture en criture O_CREAT cration du fichier sil nexiste pas O_TRUNC vider le fichier sil nest pas vide
mode Prcise les droits daccs du fichier crer : (avec des constantes symboliques comme : S_IRUSR 400, S_IWGRP 20, dfinit dans <sys/stat.h>) u g o r w x r w x r w x 400 200 100 40 20 10 4 2 1
dup2(d,1) : redirige le descripteur 1 (sortie standard) vers le descripteur d unlink : supprime un fichier (lien)
1 0
majuscul 1 0
par Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 12 0 1 2 fm
if (argc !=2) {printf ("specifier le fichier a traiter");exit(1);}
nomfe=argv[1]; sprintf(nomfm,"temp.tmp");
if(fork()==0){ int fe=open(nomfe,O_RDONLY); if(fe==-1){perror("pb ouverture de fe"); exit(1);} dup2(fe,0); int fm=open(nomfm,O_WRONLY | O_TRUNC | O_CREAT, 0666); if(fm==-1){perror("pb ou verture de fm"); exit(1);} dup2(fm,1); execlp("./majuscul","./majuscul",NULL); perror ("pb de execlp"); exit(1); }
wait(0);
if (fork()==0){ int fm=open(nomfm,O_RDONLY); if (fm==-1){perror("pb ouverture de fm");exit(1);} dup2(fm,0); unlink(nomfm); execlp("./par","./par","8",NULL); perror("pb de execlp"); exit(1); Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 13 } wait(0); } excution : $ ./majparc bonjour1.txt BONJOUR MONSIEUR 1.3.3. Redirection des entres et des sorties sur un tube 1.3.3.1. Faire communiquer deux processus Les deux processus majuscul et par peuvent communiquer laide dun tube. Le script bash serait : majparsh #!/bin/sh if [ $# -ne 1 ]; then echo "preciser le fichier a traiter" exit 1 fi nomfe=$1 ./majuscul < $nomfe | ./par 8 excution : $ ./majparsh2 bonjour1.txt BONJOUR MONSIEUR
Communication par tube entre 2 processus
Le programme majparc2.c ralise la mme fonction : majparc2.c #include<stdio.h> #include<fcntl.h> #include<unistd.h> main(int argc, char* argv[]) { char* nomfe; int p[2]; par 1 0 majuscul 0 1 pre 0 1 2 p[0] p[1] fils 0 fe p[0] p[1] 1 2 tube p Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 14
if(argc !=2) {printf ("specifier le fichier traiter"); exit(1);}
nomfe=argv[1];
if(pipe(p)==-1) {perror("pipe"); exit (1);}
if(fork()==0){ /* fils */ int fe=open(nomfe,O_RDONLY); if(fe==-1){perror("ouverture de fe");exit(1);} dup2(fe,0); /* entree standard = nomfe */ dup2(p[1],1); /* sortie standard = tube */ close(fe); /* fe est devenu inutil */ close(p[0]); /* le fils ne lit pas dans le tube */ close(p[1]); /* p[1] est devenu inutil */ execlp("./majuscul","./majuscul",NULL); perror("Pb avec execlp majuscul"); exit(1); }
/* pere */ dup2(p[0],0); /* entree standard = tube */ close(p[0]); /* p[0] est devenu inutil */ close(p[1]); /* le pere necrit pas dans le tube */ execlp("./par","./par","8",NULL); perror("Pb avec execlp par"); exit(1); } Excution $ ./majparc2 bonjour1.txt BONJOUR MONSIEUR 1.3.3.2. Rcuprer un rsultat dexcution
tube unidirectionnel date 0 1 pre 0 1 2 p[0] p[1] fils 0 p[0] p[1] 1 2 tube p Chapitre 1. Les appels systme pour les processus
Prof. C.EL AMRANI Programmation systme sous UNIX 15 lecture et criture de caractres : read, write ssize_t read (int fd, void* buf, size_t count) ; ssize_t write (int fd, void* buf, size_t count) ; avec : fd Numro de descripteur buf Adresse mmoire count Nombre de caractres lu
tubedate.c #include<stdio.h> #include<unistd.h> #include<wait.h> main() { int i, p[2]; char c, res[50];
if(pipe(p)==-1){perror("Pb tube");exit(1);}
/* fils */ if(fork()==0){ dup2(p[1],1); close(p[0]); close(p[1]); execlp("date","date","+%d/%m/%Y",NULL); perror("Pb avec execlp date"); exit(1); } /* pere */ close(p[1]); i=0; while(read(p[0],&c,1)!=0) {res[i++]=c;} res[i-1]=0; /* supprime le \n */ printf("Date du jour: %s\n",res); close(p[0]); //wait(0); }