systèmes d'exploitation et programmation concourante

76
Syst` emes d’exploitation et programmation concourante Syst` emes embarqu´ es temps r´ eel – GIF-3004 Professeur : Christian Gagn´ e Semaine 2 : 21 janvier 2020 SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagn´ e 1 / 76

Upload: others

Post on 19-Jun-2022

11 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Systèmes d'exploitation et programmation concourante

Systemes d’exploitation et programmation concourante

Systemes embarques temps reel – GIF-3004Professeur : Christian Gagne

Semaine 2 : 21 janvier 2020

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 1 / 76

Page 2: Systèmes d'exploitation et programmation concourante

Qu’est-ce qu’un systeme d’exploitation ?

Systeme d’exploitation (SE) : systeme logiciel gerant le materiel informatique et lesressources logicielles, en plus de fournir des services communs aux applications logicielles

Offre des abstractions du materiel simplifiant la vie des programmeurs, permettant degerer la complexite de ces systemes

Selon certains, les SE constitueraient une des plus complexes, si ce n’est la plus complexe,œuvres d’ingenierie existant jusqu’a present

Faire la difference entre les fonctionnalites fondamentales des SE et les fonctionnalitessupplementaires

I SE modernes avec interfaces graphiques incluent souvent une grande quantite defonctionnalites supplementaires

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 2 / 76

Page 3: Systèmes d'exploitation et programmation concourante

Fonctionnalites fondamentales des SE modernes

Gestion des processusI Processus : instance d’un programme en executionI Un processus peut contenir plusieurs threads s’executant de facon concouranteI SE en charge d’ordonnancer l’execution des processus

Gestion de la memoireI Allouer la memoire aux processusI Adressage, memoire virtuelle et pagination

Gestion des fichiersI Systeme de fichiersI Primitives d’acces aux fichiers

Gestion des peripheriquesI Communication reseauI Encapsulation des peripheriques (pilotes)

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 3 / 76

Page 4: Systèmes d'exploitation et programmation concourante

Elements d’un systeme d’exploitation

Noyau : en charge des fonctionnalites fondamentales du SE

ModesI Mode noyau (superviseur) : acces complet au materiel et peut executer toutes instructionsI Mode utilisateur : sous-ensemble des instructions possibles, limite a des ressources precises

Interface utilisateurI Shell : inevitable en embarqueI Interface graphique (GUI)I A strictement parler, ces interfaces ne font pas parti des SE

Interface de programmationI Fonctionnalites du SE disponibles par des appels de fonctions

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 4 / 76

Page 5: Systèmes d'exploitation et programmation concourante

Environnement d’un systeme d’exploitation

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 5 / 76

Page 6: Systèmes d'exploitation et programmation concourante

Linux

Unix : famille de systemes d’exploitation multitache et multiutilisateursI Origine d’AT&T, fin annees 1960, concu pour etre portable, base sur une certaine philosophieI Modele de systeme d’exploitation generique, utilisable a differentes echelles (embarque

autant que supercalculateurs)I Deux variantes historiques (AT&T et Berkeley) et un clone open source (GNU / Linux)

Langage C : developpe par la meme equipe que UnixI Concu pour se compiler efficacement en code machineI Element central pour rendre Unix portable

Linux : un noyau et un systeme completI Noyau monolithique cree par Linus Torvald en 1991, activement developpe par la

communauteI Reimplementation de l’environnement Unix (compilateur, commandes, librairies, etc.) dans le

projet GNU

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 6 / 76

Page 7: Systèmes d'exploitation et programmation concourante

Structure du noyau de Linux

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 7 / 76

Page 8: Systèmes d'exploitation et programmation concourante

Philosophie Unix

This is the Unix philosophy : Write programs to do one thing and do it well. Writeprograms to work together. Write programs to handle text streams, because that is auniversal interface.

– Doug McIlroy

Plusieurs programmes et librairies simplesI Des commandes simples comme ls ou cd sont des programmes independants

Interactions entre programmes via interface textuelleI ls -l /etc/ | grep conf | less

Modularisation elevee, avec organisation en couches d’abstractions diversesI Par opposition a des librairies monolithiques et verticales

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 8 / 76

Page 9: Systèmes d'exploitation et programmation concourante

Organisation en couches dans Linux

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 9 / 76

Page 10: Systèmes d'exploitation et programmation concourante

POSIX

Portable Operating System Interface (POSIX) : standard de l’IEEE pour maintenir laportabilite entre les systemes d’exploitation

I Portabilite au niveau des interfaces de programmation, recompilation necessaire desprogrammes d’une architecture a l’autre

I Portabilite du terminal (shell), avec utilitaires standardisesI Inspire fortement de Unix, etant donne qu’il etait « neutre »I Les variantes modernes de Unix (incluant Linux, macOS) l’ont adopte, present egalement

dans d’autres SE (ex. Windows Subsystem for Linux)

Composantes de POSIXI Processus, communication interprocessus, signauxI E/S (terminal, fichier, reseau)I Threads et primitives de synchronisationI Shell et commandes

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 10 / 76

Page 11: Systèmes d'exploitation et programmation concourante

Shell

Deux modes d’interactions avec le shellI Interactif, avec echange de commandes et de sorties correspondantesI Script, representant suites de commandes a executer

F Scripts peuvent etre des programmes assez complexesF Enonces conditionnels (si-alors), boucles, appels de fonctions

Mode interactifI $ date

Mon 16 Jan 2017 11:19:09 ESTI $ date > date.txt

$ cat date.txt

Mon 16 Jan 2017 11:19:15 ESTI $ cat fichier1 fichier2 fichier3 | sort > /dev/lpI $ cat fichier1 fichier2 fichier3 | sort > /dev/lp &

Plus sur la ligne de commande interactive a l’atelier de vendredi

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 11 / 76

Page 12: Systèmes d'exploitation et programmation concourante

Exemple d’un script

1 #!/bin/bash

2 # Compter le nombre de lignes dans une liste de fichiers

3 if [ $# -lt 1 ]

4 then

5 echo "Usage: $0 fichiers ..."

6 exit 1

7 fi

8 echo "$0 compte les lignes de code"

9 l=0

10 n=0

11 s=0

12 for f in $*

13 do

14 l=`wc -l $f | sed 's/^\([0-9]*\).*$/\1/'`15 echo "$f: $l"

16 n=$[ $n + 1 ]

17 s=$[ $s + $l ]

18 done

19 echo "$n fichiers avec un total de $s lignes"

Inspire de https://www.macs.hw.ac.uk/~hwloidl/Courses/LinuxIntro/x945.html

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 12 / 76

Page 13: Systèmes d'exploitation et programmation concourante

Quelques commandes usuelles

Programme Usage typiquecat Concatener plusieurs fichiers vers la sortie standardchmod Changer les modes de protection des fichierscp Copier un ou plusieurs fichiersgrep Rechercher certains patrons dans un fichierhead Extraire les premieres lignes d’un fichierls Lister le contenu d’un repertoiremkdir Creer un repertoiremv Deplacer ou renommer un fichier/repertoireps Lister les processus en cours d’executionrm Effacer un ou plusieurs fichiersrmdir Effacer un repertoiresort Trier un fichier alphabetiquementtail Extraire les dernieres lignes d’un fichier

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 13 / 76

Page 14: Systèmes d'exploitation et programmation concourante

Le manuel

Documentation indispensable dans Unix : le manuelI Appele par la commande man dans le shell

$ man ls

LS(1) BSD General Commands Manual LS(1)

NAME

ls -- list directory contents

SYNOPSIS

ls [-ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1] [file ...]

DESCRIPTION

For each operand that names a file of a type other than directory, ls

displays its name as well as any requested, associated information. For

each operand that names a file of type directory, ls displays the names

of files contained within that directory, as well as any requested, asso-

ciated information.

[...]

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 14 / 76

Page 15: Systèmes d'exploitation et programmation concourante

Le manuel

Documente elements varies du SEI Plusieurs sections du manuel

F Section 1 : commandes generalesF Section 2 : appels au systemeF Section 3 : librairies de fonction, en particulier du langage CF Etc.

I Choix de la section du manuel avec argument numeriqueF man 1 printf : commande shellF man 3 printf : fonction C

Interface Web du manuel https://www.kernel.org/doc/man-pages/

If all else fails, read the manual

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 15 / 76

Page 16: Systèmes d'exploitation et programmation concourante

Processus

Processus : programme en cours d’executionI Une des plus anciennes et plus importantes abstractions d’un SEI Permet des operations pseudo-concourantes sur un seul processeurI Un programme n’est pas un processus (analogie a une classe vs un objet en programmation

OO)

Processeur donne la main aux processus actifs pour une courte periode (10-100 ms)I Un seul processus actif a la fois sur un processeurI Changement de processus fait volontairement (ex. attente sur un evenement) ou par

preemption

SE en charge de conserver information sur etat des processus

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 16 / 76

Page 17: Systèmes d'exploitation et programmation concourante

Execution de plusieurs processus

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 17 / 76

Page 18: Systèmes d'exploitation et programmation concourante

Creation de processus

Sources principales de creation de processusI Initialisation du systeme

F Processus interagissant avec l’utilisateurF Processus d’arriere-plan (daemons)

I Appel a une routine de creation de processus par processus existantF Processus aidant un autre a accomplir sa tache

I Requete de l’utilisateur de creer un processusF Utilisateur clique sur une icone ou tape une commande dans le terminal

I Initialisation d’une tache de maintenanceF Lancer tache de maintenance sur serveurs, lorsque ressources disponibles

Techniquement, tous ces cas reviennent a creer un nouveau processus a partir d’unprocessus existant

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 18 / 76

Page 19: Systèmes d'exploitation et programmation concourante

Creation de processus dans Unix

Pour creer un nouveau processus dans Unix : forkI Fait un clone complet (processus enfant) du processus parentI Meme usage memoire, memes variables d’environnement, memes fichiers ouverts

#include <unistd.h>

pid_t fork(void);

I Retourne le ID du processus enfant au parent et 0 a l’enfant

Mutation du processus : fonction execveI Execute un nouveau programme dans le processus actuel

#include <unistd.h>

int execve(const char *path, char *const argv[], char *const envp[]);

Solutions pour partage de la memoireI Memoire du programme partagee, memoire des donnees copieeI Alternativement, partage de la memoire avec copy-on-write

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 19 / 76

Page 20: Systèmes d'exploitation et programmation concourante

Execution d’une commande

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 20 / 76

Page 21: Systèmes d'exploitation et programmation concourante

Terminaison d’un processus

Condition pour terminer un processusI Sortie normale (volontaire)

F Fin du programme rencontree ; utilisateur a demande de quitter le programme

I Sortie avec erreur (volontaire)F Programme rencontre une situation anormale et quitteF Code d’erreur generalement retourne

I Erreur fatale (involontaire)F Acces memoire inexistante ; instruction illegale

I Tue par un autre processus (involontaire)F Appel systeme pour tuer un autre processusF Fonction systeme et commande kill dans Unix

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 21 / 76

Page 22: Systèmes d'exploitation et programmation concourante

Hierarchie de processus

Dans Unix, relation persiste entre processus parent et enfantI Tous les descendants d’un processus forment un groupeI Signal transmis a tous les processus d’un groupe

F Ex. signal au clavier (CTRL-C par exemple) transmis au groupe de processus du terminalF Processus peuvent attraper le signal, l’ignorer, ou effectuer l’action par defaut (quitter)

Tous les processus Unix proviennent directement ou indirectement du processus init,present dans l’image de demarrage

I init lance un processus pour chaque terminalI Utilisateur se connectant sur un terminal lance un shell, qui accepte des commandesI Ensemble des processus est un arbre avec init a la racine

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 22 / 76

Page 23: Systèmes d'exploitation et programmation concourante

Terminaison de processus enfant

Attendre pour la terminaison de processus enfant : wait et waitpid

#include <sys/wait.h>

pid_t wait(int *stat_loc);

pid_t waitpid(pid_t pid, int *stat_loc, int options);

I Retourne PID du processus enfant ayant termine, -1 s’il y a une erreurI stat_loc : contient information sur statut du processus ayant termineI Options donnees dans un masque

F WNOHANG : rendre l’appel non-bloquantF WUNTRACED : intercepte des processus arretes (mais non termines)

Macros pour traiter le statut du processus (stat_loc)I WIFEXITED : terminaison normaleI WIFSIGNALED : terminaison suite a reception d’un signalI WIFSTOPPED : processus arrete (mais non termine)I WEXITSTATUS : code de retour lors de terminaisonI WTERMSIG / WSTOPSIG : numero du signal de terminaison / d’arret

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 23 / 76

Page 24: Systèmes d'exploitation et programmation concourante

Exemple avec fork et waitpid

1 #include <sys/wait.h>

2 #include <stdlib.h>

3 #include <unistd.h>

4 #include <stdio.h>

5

6 int main(int argc, char *argv[]) {

7 pid_t cpid, w;

8 int status;

9

10 cpid = fork();

11 if (cpid == -1) {

12 perror("fork");

13 exit(EXIT_FAILURE);

14 }

15

16 if (cpid == 0) { /* Code executed by child */

17 printf("Child PID is %ld\n", (long) getpid());

18 if (argc == 1) pause(); /* Wait for signals */

19 _exit(atoi(argv[1]));

Tire de man 2 waitpid

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 24 / 76

Page 25: Systèmes d'exploitation et programmation concourante

Exemple avec fork et waitpid

22 } else { /* Code executed by parent */

23 do {

24 w = waitpid(cpid, &status, WUNTRACED);

25 if (w == -1) {

26 perror("waitpid");

27 exit(EXIT_FAILURE);

28 }

29

30 if (WIFEXITED(status)) {

31 printf("exited, status=%d\n", WEXITSTATUS(status));

32 } else if (WIFSIGNALED(status)) {

33 printf("killed by signal %d\n", WTERMSIG(status));

34 } else if (WIFSTOPPED(status)) {

35 printf("stopped by signal %d\n", WSTOPSIG(status));

36 }

37 } while (!WIFEXITED(status) && !WIFSIGNALED(status));

38 exit(EXIT_SUCCESS);

39 }

40 }

Tire de man 2 waitpid

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 25 / 76

Page 26: Systèmes d'exploitation et programmation concourante

Processus zombie

Processus enfant ayant termineI Processus enfant reste actif tant que statut n’est pas lu par le processus parentI Important de faire un wait ou waitpid sur les processus enfantsI Sinon, lors de la terminaison, le processus enfant devient « zombie »

F Processus zombie est en attente de lecture de statutF Les processus zombie peuvent encombrer la table des processus

I Processus parent est notifie par un signal (SIGCHLD) de la terminaison d’un processus enfant

Processus parent termine avant ses processus enfantsI Processus init adopte les processus orphelinsI Lit le statut aussitot que disponible

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 26 / 76

Page 27: Systèmes d'exploitation et programmation concourante

Etat d’execution d’un processus

Supposons la commande cat chap1 chap2 chap3 | grep arbreI Processus du programme cat concatene le contenu des trois fichiersI Processus du programme grep selectionne les lignes contenant le mot arbreI Si les fichiers sont moindrement volumineux, grep va devoir attendre le resultat de cat

avant de proceder

Trois etats d’execution possible d’un processusI En execution (utilise presentement le processeur)I En attente (arret temporaire, pret a etre execute)I Bloque (ne peut etre execute tant qu’un evenement externe survient)

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 27 / 76

Page 28: Systèmes d'exploitation et programmation concourante

Implementation des processus

SE maintient une structure de donnees appelee table de processusI Une entree par processusI Contient l’etat du processus complet

F Compteur de programme et autres registresF Pointeur a la pile et memoire alloueeF Information pour la maintenance et l’ordonnancement

Effet d’une interruption1 Empilement du compteur de programme (fait par materiel)2 Chargement du nouveau compteur de programme (fait par materiel)3 Sauvegarde des registres (en assembleur)4 Construction d’une nouvelle pile (en assembleur)5 Fonction de service de l’interruption (en C)6 Ordonnanceur decide quel processus executer (en C)7 Lancement du nouveau processus (en assembleur)

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 28 / 76

Page 29: Systèmes d'exploitation et programmation concourante

Table de processus

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 29 / 76

Page 30: Systèmes d'exploitation et programmation concourante

Threads

Threads : mini-processus roulant a l’interieur d’un processusI Fonctionnent a l’interieur du meme espace memoireI Un processus comporte un ou plusieurs fils de controle (threads) independants

Raisons pour le multithreadingI Facilite de programmation

F Souvent, une application comporte plusieurs activitesF Certaines activites bloquent de temps en tempsF Plusieurs fils sequentiels executes en quasi parallele rendent la programmation plus aisee

I Rapidite de la creationF Selon le SE, creation d’un thread est 10 a 100 fois plus rapide qu’un processusF Utile si dynamique importante de la creation et destruction des threads

I PerformanceF Utilisation efficace des ressources, pour gestion des E/SF Exploitation de systemes multiprocesseurs

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 30 / 76

Page 31: Systèmes d'exploitation et programmation concourante

Difference entre processus et threads

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 31 / 76

Page 32: Systèmes d'exploitation et programmation concourante

Difference entre processus et threads

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 32 / 76

Page 33: Systèmes d'exploitation et programmation concourante

Identification de threads

#include <pthread.h>

int pthread_equal(pthread_t tid1, pthread_t tid);

pthread_t pthread_self(void);

Chaque thread a un identifiant unique, specifique au processus

Sous Linux, pthread_t correspond a un unsigned long, sous macOS et BSD, unpointeur, et sous Solaris, un unsigned int

Utile pour assigner des taches a des threads precis

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 33 / 76

Page 34: Systèmes d'exploitation et programmation concourante

Creation de threads

#include <pthread.h>

int pthread_create(pthread_t *restrict tidp,

const pthread_attr_t *attr,

void *(*start_rtn)(void *),

void *arg);

tidp : ID du thread nouvellement cree

attr : attributs du thread

start_rtn : pointeur a la routine a executer dans le nouveau thread

arg : argument donne a la fonction pointee par start_rtn lors de son appel

Retourne 0 si lancement avec succes du thread, code d’erreur autrement

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 34 / 76

Page 35: Systèmes d'exploitation et programmation concourante

Terminaison de threads

Trois facons de terminer un threadI Le thread a retourne de la routine appelee par pthread_createI Le thread a ete annule par un autre thread du meme processusI Le thread a appele la fonction pthread_exit

#include <pthread.h>

void pthread_exit(void *rval_ptr);

rval_ptr contient information passee aux autres threads, obtenu via fonctionpthread_join

#include <pthread.h>

int pthread_join(pthread_t thread, void **rval_ptr);

I Fonction pthread_join bloque tant que thread ne termine pas

Si routine appelee par pthread_create se termine, rval_ptr contient valeur de retour

Si thread est annule par un autre thread, rval_ptr pointe a PTHREAD_CANCELLED

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 35 / 76

Page 36: Systèmes d'exploitation et programmation concourante

Annuler un thread

Autre thread du processus peut etre annule avec fonction pthread_cancel

#include <pthread.h>

int pthread_cancel(pthread_t tid);

I Comme si on faisait appel a pthread_exit dans le thread annule, avec valeurPTHREAD_CANCELLED comme argument

I Appel non bloquant, retourne aussitot la requete terminee sans attendre la fin du threadF Pas de garantie stricte sur la terminaison effective du thread

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 36 / 76

Page 37: Systèmes d'exploitation et programmation concourante

Gestion des terminaisons

#include <pthread.h>

void pthread_cleanup_push(void (*routine)(void *),

void *arg);

void pthread_cleanup_pop(int execute);

pthread_cleanup_push : ajoute fonction routine sur la pile, qui sera appelee avecargument arg lors de terminaisonCas ou routines de cleanup sont appelees

I pthread_exit est appeleI Demande d’annulation recue par le thread (via pthread_cancel)I Appel pthread_cleanup_pop avec valeur autre que 0 pour execute

pthread_cleanup_pop : retire fonction de terminaison la plus haute de la pilePour chaque pthread_cleanup_push, on doit avoir pthread_cleanup_popcorrespondant dans la portee d’une fonction (donne en paires)

I Parce que peut etre implemente comme des macros

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 37 / 76

Page 38: Systèmes d'exploitation et programmation concourante

Reception du status de terminaison

Par defaut, statut de terminaison retenu tant que pthread_join n’est pas appele pour lethread

I Ressources consommees si plusieurs threads se terminent sans appel a pthread_join

On peut liberer completement l’espace associe au thread lors de terminaison en ledetachant

#include <pthread.h>

int pthread_detach(pthread_t thread);

I Retourne 0 si detachement a reussi, sinon code d’erreurI On peut detacher un thread au lancement via un attribut lors de l’appel a pthread_create

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 38 / 76

Page 39: Systèmes d'exploitation et programmation concourante

Attributs de threads

Attributs de threads peuvent etre specifies

#include <pthread.h>

int pthread_attr_init(pthread_attr_t *attr);

int pthread_attr_destroy(pthread_attr_t *attr);

Attribut standard pertinent : detachstate

#include <pthread.h>

int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);

int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

I Assigner a PTHREAD_CREATE_DETACHED pour creer thread detache, ouPTHREAD_CREATE_JOINABLE pour creer attache (par defaut)

Attributs standards pour manipuler pile d’appels du thread (usage avance)

Attributs non standards peuvent etre definis (ex. pour du temps reel)

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 39 / 76

Page 40: Systèmes d'exploitation et programmation concourante

Comparaison primitives POSIX de processus et threads

Processus Thread Descriptionfork pthread_create Creer un nouveau flot de controleexit pthread_exit Quitter un flot de controle existantwaitpid pthread_join Obtenir statut de terminaison d’un flot de controleatexit pthread_cleanup_push Enregistrer une fonction qui sera appelee a la terminaison d’un flot

de controlegetpid pthread_self Obtenir ID du flot de controleabort pthread_cancel Demander une terminaison irreguliere d’un flot de controle

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 40 / 76

Page 41: Systèmes d'exploitation et programmation concourante

Implementation du multithreading

Deux approches principales pour implementer threadsI Implementation dans processus

F Simplifie l’implementation du noyau, qui ne gere pas les threadsF Changement de thread plus efficace qu’avec appel au noyauF Appels bloquants a routine du SE problematiquesF Preemption entre threads d’un processus doit etre volontaireF Courant dans les anciens SE, pour permettre les threads sans devoir modifier le noyau

I Implementation dans le noyauF Couts de creation et de destruction de threads beaucoup plus importants (appels systemes

demandant de passer en mode noyau)F Ne requiert pas de nouvelles fonctions non bloquantes du SEF Ordonnancement des threads beaucoup plus efficace (ex. lors de manquement de page)

Dans Linux, threads implementes comme processus particuliers (lightweight process), separtageant la memoire

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 41 / 76

Page 42: Systèmes d'exploitation et programmation concourante

Etat de concurrence

Threads dans un processus se partagent la memoireI Un thread peut acceder a l’ensemble de la memoire de son processus, sans contrainteI Partage et echange d’information entre threads par memoire partageeI Risque d’incoherence si lecture-ecriture ou ecriture-ecriture simultanees

Etat de concurrence (race condition) : situation ou deux ou plusieurs threads (ouprocessus) lisent et ecrivent des donnees partagees et que le resultat depend de quelthread s’est execute a quel moment

I Debogger des etats de concurrence est arduI Ex. : executer dans certaines conditions peut toujours donner des resultats valides, mais avec

un leger changement de conditions peut mener a d’autres resultats (ou une erreur)

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 42 / 76

Page 43: Systèmes d'exploitation et programmation concourante

Probleme du producteur-consommateur

Deux threads roulent en concurrence sur un processeurI Thread producteur : produit des donnees qui sont ajoutees dans le tableau partageI Thread consommateur : retire des donnees du tableau partage

Problemes lorsque tableau plein ou videI Lorsque tableau plein, producteur se met en veille, se reveillant lorsque consommateur a

retire des donneesI Lorsque tableau vide, consommateur se met en veille, se reveillant lorsque producteur a

ajoute des donnees

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 43 / 76

Page 44: Systèmes d'exploitation et programmation concourante

Probleme du producteur-consommateur

1 #define N 100 // Taille du tableau

2 int count = 0; // Nombre d'elements presentement dans le tableau

3 void producer(void) {

4 int item;

5 while(1) {

6 item = produce_item();

7 if(count == N) sleep();

8 insert_item();

9 count = count + 1;

10 if(count == 1) wakeup(consumer);

11 }

12 }

13 void consumer(void) {

14 int item;

15 while(1) {

16 if(count == 0) sleep();

17 item = remove_item();

18 count = count - 1;

19 if(count == N-1) wakeup(producer);

20 consume_item(item);

21 }

22 }

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 44 / 76

Page 45: Systèmes d'exploitation et programmation concourante

Probleme du producteur-consommateur

Etat de concurrence avec probleme du producteur-consommateurI Tableau vide, consommateur viens de lire que count vaut 0 (ligne 16)I Ordonnanceur change de thread avant que consommateur soit en veille, executant producteurI Producteur ajoute element au tableau, incremente count (lignes 8 et 9)I Comme count vaut maintenant 1, reveille consommateur (ligne 10)I Mais consommateur n’est pas en veille et signal de reveil est perduI Prochaine execution du consommateur, il va se mettre en veilleI Producteur va remplir le tableau et aussi se mettre en veilleI Les deux threads sont en veille, attendant l’un apres l’autre

Essence du probleme : signal de reveil envoye avant que l’autre thread soit en veilleI Courses entre threads doivent etre bien encadreesI Preemption a moments arbitraires genere des bogues parfois tres difficiles a trouver

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 45 / 76

Page 46: Systèmes d'exploitation et programmation concourante

Primitive d’exclusion mutuelle

Controler les acces aux sections critiques est necessaireI Primitive couramment utilisee a cette fin : MUTEX (MUTual EXclusion)

Mutexes peuvent etre bloques (lock) et debloques (unlock) par des operations atomiquesI Operations atomiques ne peuvent etre preempteesI Souvent implemente a l’aide d’une primitive materiel

F Typiquement, instruction test-and-set : copie valeur d’un emplacement memoire dans registreet ecrit valeur 1 dans emplacement memoire

1 mutex_lock:

2 TSL REGISTER,MUTEX ; Copie MUTEX dans REGISTER et ecrit 1 dans MUTEX

3 CMP REGISTER,#0 ; est-ce que MUTEX egal 0?

4 JZE ok ; si MUTEX vaut 0, mutex libere et on retourne

5 CALL thread_yield ; sinon mutex bloque, passe a un autre thread

6 JMP mutex_lock ; retour au debut pour reprendre mutex

7 ok: RET ; bloque, retour a l'appelant (section critique)

89 mutex_unlock:

10 MOVE MUTEX,#0 ; Ecrit 0 dans le mutex

11 RET ; Retour a l'appelant

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 46 / 76

Page 47: Systèmes d'exploitation et programmation concourante

Exclusion mutuelle

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 47 / 76

Page 48: Systèmes d'exploitation et programmation concourante

Mutex POSIX

Creation et destruction de mutex POSIX

#include <pthread.h>

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t attr);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

I Retourne 0 si execution correcte, code d’erreur autrementI Utiliser NULL pour attr pour creer mutex avec attributs par defaut

Bloquer/debloquer mutex POSIX

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

I pthread_mutex_lock bloquant, retourne lorsque mutex obtenuI pthread_mutex_trylock non bloquant, retourne meme si le mutex non disponible (valeur

de retour EBUSY)

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 48 / 76

Page 49: Systèmes d'exploitation et programmation concourante

Attributs de mutex

Mutexes peuvent etre crees avec differents attributs

#include <pthread.h>

int pthread_mutexattr_init(pthread_mutexattr_t *attr);

int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);

Modifier types de mutex

#include <pthread.h>

int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);

int pthread_mutexattr_settype(const pthread_mutexattr_t *attr, int type);

I PTHREAD_MUTEX_NORMAL : mutex standard sans verification d’erreursI PTHREAD_MUTEX_ERRORCHECK : mutex faisant verification d’erreursI PTHREAD_MUTEX_RECURSIVE : permet de bloquer plusieurs fois le meme mutex par meme

thread sans inter blocageF Maintient compte de blocage, libere seulement lorsque autant de deblocages que de blocages

prealables effectues

I PTHREAD_MUTEX_DEFAULT : modele par defaut, peut etre un des trois precedents selonl’implementation

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 49 / 76

Page 50: Systèmes d'exploitation et programmation concourante

Reader-Writer Locks

Avec mutex, l’etat est soit bloque, soit debloqueI Ecriture de valeurs : exclusion mutuelle est necessaireI Lectures simultanees de valeurs : acces simultanes peuvent etre possibles

Primitive POSIX de reader-writer locks

#include <pthread.h>

int pthread_rwlock_init(pthread_rwlock_t *rwlock,

const pthread_rwlockattr_t *attr);

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

I Coherent avec interface de mutex, mais acces simultanes en lecture permis

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 50 / 76

Page 51: Systèmes d'exploitation et programmation concourante

Conditions

Condition : permettre a des threads de se synchroniser

#include <pthread.h>

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);

int pthread_cond_destroy(pthread_cond_t *cond);

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 51 / 76

Page 52: Systèmes d'exploitation et programmation concourante

Conditions

Attendre qu’une condition soit satisfaite

#include <pthread.h>

int pthread_cond_wait(pthread_cond_t *cond,

pthread_mutex_t *mutex);

I Chaque condition est protegee par un mutexI Thread doit acquerir mutex avant d’evaluer ou changer la conditionI Mutex libere durant l’attente

Signaler qu’une condition est satisfaite

#include <pthread.h>

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

I pthread_cond_signal reveille au moins un thread en attenteI pthread_cond_broadcast reveille tous les threads en attente

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 52 / 76

Page 53: Systèmes d'exploitation et programmation concourante

Probleme du producteur-consommateur

Solution au probleme du producteur-consommateur avec mutex et conditionsI Solution tiree de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems.

Prentice Hall Press, 2015.

1 #include <stdio.h>

2 #include <pthread.h>

34 #define MAX 100000000

5 pthread_mutex_t the_mutex;

6 pthread_cond_t condc, condp;

7 int buffer = 0;

89 void* producer(void *ptr) {

10 for(int i=1; i<=MAX; ++i) {

11 pthread_mutex_lock(&the_mutex);

12 while(buffer != 0) pthread_cond_wait(&condp, &the_mutex);

13 buffer = i;

14 pthread_cond_signal(&condc);

15 pthread_mutex_unlock(&the_mutex);

16 }

17 pthread_exit(0);

18 }

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 53 / 76

Page 54: Systèmes d'exploitation et programmation concourante

Probleme du producteur-consommateur

19 void* consumer(void *ptr) {

20 for(int i=1; i<=MAX; ++i) {

21 pthread_mutex_lock(&the_mutex);

22 while(buffer == 0) pthread_cond_wait(&condc, &the_mutex);

23 buffer = 0;

24 pthread_cond_signal(&condp);

25 pthread_mutex_unlock(&the_mutex);

26 }

27 pthread_exit(0);

28 }

29 int main(int argc, char **argv) {

30 pthread_t pro, con;

31 pthread_mutex_init(&the_mutex, NULL);

32 pthread_cond_init(&condc, NULL);

33 pthread_cond_init(&condp, NULL);

34 pthread_create(&con, NULL, consumer, NULL);

35 pthread_create(&pro, NULL, producer, NULL);

36 pthread_join(pro, NULL);

37 pthread_join(con, NULL);

38 pthread_cond_destroy(&condp);

39 pthread_cond_destroy(&condc);

40 pthread_mutex_destroy(&the_mutex)

41 }

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 54 / 76

Page 55: Systèmes d'exploitation et programmation concourante

Barrieres

Barrieres : synchroniser plusieurs threads s’executant en parallele

#include <pthread.h>

int pthread_barrier_init(pthread_barrier_t barrier,

const pthread_barrierattr_t *attr,

unsigned int count);

int pthread_barrier_destroy(pthread_barrier_t *barrier);

int pthread_barrier_wait(pthread_barrier_t *barrier);

I pthread_barrier_wait : threads en veille tant que le compte de la barriere n’est pas atteintI Compte de la barriere donne comme argument count de la fonction pthread_barrier_init

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 55 / 76

Page 56: Systèmes d'exploitation et programmation concourante

Barrieres

Tire de Andrew S. Tanenbaum et Herbert Bos. Modern Operating Systems. Prentice Hall Press, 2015.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 56 / 76

Page 57: Systèmes d'exploitation et programmation concourante

Fonctions reentrantes

Fonction reentrantesI Plusieurs executions simultanees de la fonctions possiblesI Exemple problematique : malloc

F Allocation dynamique de memoire demande de modifier structure de donnee interneF Si deux ou plusieurs threads modifient la structure de donnees simultanement, serieux

problemes en perspective

Deux strategies principalesI Utiliser mutex et autres primitives pour proteger sections critiques

F Engendre surcout significatifs, autant pour processus a un thread que multithreade

I Ne pas utiliser de variables globales, utiliser seulement arguments de la fonctionF Exige de modifier l’APIF Expose structure de donnees internes a l’utilisateur

Implementation modernes offrent fonction reentrantesI Par defaut, fonctions dans POSIX sont reentrantesI Pour les exceptions, existe souvent version _r qui est reentrante (ex. asctime vs asctime_r)

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 57 / 76

Page 58: Systèmes d'exploitation et programmation concourante

Lecture de fichiers et multithreading

Acces a un fichier par plusieurs threads peut etre problematiqueI Fonctions standards sont reentrantesI Mais les performances peuvent se degrader si on ne fait pas attention

F Chaque appel requiert d’acquerir un lock interne (appel au SE)F Repeter lecture de quelques caracteres a la fois peut etre tres couteux

Solution : laisser application decider du moment ou lock doit etre fait

#include <stdio.h>

int ftrylockfile(FILE *fp);

void flockfile(FILE *fp);

void funlockfile(FILE *fp);

int getchar_unlocked(void);

int getc_unlocked(FILE *fp);

int putchar_unlocked(int c);

int putc_unlocked(int c, FILE *fp);

I Quatre dernieres fonctions doivent etre encadrees par flockfile (ou ftrylockfile) etfunlockfile

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 58 / 76

Page 59: Systèmes d'exploitation et programmation concourante

Communication inter processus

Processus dans SE modernes sont independants, sans memoire partageeI Comme echanger de l’information entre processus ?

Communication inter processus dans UnixI PipesI FIFOI Files de messagesI SemaphoresI Memoire partageeI Sockets

Plusieurs concepts definis alors que threads n’existaient pasI Pour le cours, on se limite aux pipes et socketsI Memoire partagee et semaphores se font naturellement avec des threads

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 59 / 76

Page 60: Systèmes d'exploitation et programmation concourante

Pipes

Pipes (en francais, canaux de communication) : forme plus ancienne de communicationinter processus dans Unix

I Canal unidirectionnel entre deux processusI En general utilise seulement entre processus ayant un ancetre commun

F Cree par un parent avant de faire un fork, herite par l’enfant

Creation d’un pipe

#include <unistd.h>

int pipe(int fd[2]);

I Deux descripteurs de fichiers retournes par la fonctionF fd[0] ouvert en lecture et fd[1] ouvert en ecritureF Sortie de fd[1] est entree de fd[0]

I Apres fork, processus doivent fermer descripteurs de fichier non utilisesF Canal du parent vers l’enfant, parent ferme fd[0], enfant ferme fd[1]

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 60 / 76

Page 61: Systèmes d'exploitation et programmation concourante

Lecture / ecriture dans un pipe

Information transmise par les fonctions read et write, comme pour un fichier regulierI Un pipe se comporte comme un fichierI Lorsqu’on fait un read sur pipe dont bout d’ecriture (fd[1]) est ferme, retourne 0 (EOF)I Lorsqu’on fait un write sur pipe dont bout de lecture (fd[0]) est ferme, signal SIGPIPE est

genereF Si on gere le signal SIGPIPE, write retourne -1

Pour un canal bidirectionnel, il faut creer deux pipes, un pour chaque direction

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 61 / 76

Page 62: Systèmes d'exploitation et programmation concourante

Exemple avec pipes

1 #include <unistd.h>

2 int main(void) {

3 int n, fd[2];

4 pid_t pid;

5 char line[MAXLINE];

6 if(pipe(fd) < 0) err_sys("pipe error");

7 if((pid = fork()) < 0) err_sys("fork error");

8 else if (pid > 0) { /* parent */

9 close(fd[0]);

10 write(fd[1], "Hello, world!\n", 14);

11 } else { /* enfant */

12 close(fd[1]);

13 n = read(fd[0], line, MAXLINE);

14 write(STDOUT_FILENO, line, n);

15 }

16 exit(0);

17 }

Tire de W. Richard Stevens et Stephen A. Rago. Advanced programming in the UNIX environment. Addison-Wesley, 2013.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 62 / 76

Page 63: Systèmes d'exploitation et programmation concourante

Fonctions popen et pclose

Operation commune : lancer un processus pour lire sa sortie ou fournir son entree

#include <stdio.h>

FILE* popen(const char* cmdstring, const char* type);

int pclose(FILE *fp);

I popen fait fork et exec pour executer programme cmdstring et retourne pointeur defichier aux E/S standards

I Si argument type est "r", pointeur de fichier retourne est sortie standard de cmdstringI Si valeur a argument type est "w", pointeur de fichier retourne est entree standard de

cmdstringI pclose ferme E/S standard, attend la commande pour terminer et retourne le statut de

terminaisonI Commande cmdstring executee dans un shell Bourne, comme

sh -c cmdstring

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 63 / 76

Page 64: Systèmes d'exploitation et programmation concourante

Sockets Unix

Socket Unix : interface de communication bidirectionnelleI Communication bidirectionnelle et entre processus pas necessairement relatesI Interface similaire pour communication TCP/IP

Fonction pour pipes bidirectionnels

#include <sys/socket.h>

int socketpair(int domain, int type,

int protocol, int sockfd[2]);

I Interface general, mais portable seulement pour sockets de domaine Unix (domain=AF_UNIX)

int fd[2];

socketpair(AF_UNIX, SOCK_STREAM, 0, fd);I Type : flot (SOCK_STREAM) ou datagram (SOCK_DGRAM)

F Datagram preserve frontieres entre messages, alors que flot ne le fait pasF Taille limite imposee sur messages avec datagram

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 64 / 76

Page 65: Systèmes d'exploitation et programmation concourante

Sockets Unix

Sockets crees par socketpair sont connectes, mais anonymesI Connections entre processus non relates impossible

Interface general des sockets (IP et Unix)

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

I Domaine : AF_INET (IPv4), AF_INET6 (IPv6), AF_UNIX (Unix), AF_UNSPEC (non specifie)I Type : SOCK_DGRAM (datagram), SOCK_RAW (protocole IP brut), SOCK_SEQPACKET (sequence

taille fixe), SOCK_STREAM (flot sequentiel)I Protocole : selon le domain utilise

Creer un socket Unix (datagram)

int fd = socket(AF_UNIX, SOCK_DGRAM, 0);

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 65 / 76

Page 66: Systèmes d'exploitation et programmation concourante

Sockets nommes

Assigner socket Unix a une adresse (nom)

struct sockaddr_un {

sa_family_t sun_family; /* AF_UNIX */

char sun_path[108]; /* Nom du chemin */

}

Nom du chemin est pour publier le socketI SE cree fichier du meme nomI Fichier sun_path ne peut etre ouvert, seulement pour publier le nom

Associer socket a l’adresse avec fonction bind

#include <sys/socket.h>

int bind(int sockfd,

const struct sockaddr* addr,

socklen_t len);

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 66 / 76

Page 67: Systèmes d'exploitation et programmation concourante

Exemple : connexion a un socket Unix nomme

1 #include <sys/socket.h>

2

3 int main(void) {

4 struct sockaddr_un un;

5 un.sunfamily = AF_UNIX;

6 strcpy(un.sun_path, "foo.socket");

7 if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)

8 err_sys("socket failed!");

9 size = offsetof(struct sockaddr_un, un.sun_path) +

10 strlen(un.sun_path);

11 if(bind(fd, (struct sockaddr*)&un, size) < 0)

12 err_sys("bind failed!");

13 printf("UNIX domain socket bound\n");

14 exit(0);

15 }

Tire de W. Richard Stevens et Stephen A. Rago. Advanced programming in the UNIX environment. Addison-Wesley, 2013.

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 67 / 76

Page 68: Systèmes d'exploitation et programmation concourante

Protocole oriente connections

Protocole sans connexion (SOCK_DGRAM)I Une fois bind sur adresse effectue, serveur pret a recevoir messagesI Client se connecte par fonction connect

Protocole oriente connexion (SOCK_STREAM)I Cote serveur

F bind : se lie a une adresseF listen : se prepare a recevoir demandes de connectionsF accept : cree un nouveau socket pour accepter nouvelle connexion et la communiquer avec

client

I Cote client : se connecter a un serveur avec fonction connect

Echange des donneesI send (aussi write) : envoyer/ecrire un messageI recv (aussi read) : recevoir/lire un message

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 68 / 76

Page 69: Systèmes d'exploitation et programmation concourante

Serveur avec sockets Unix

Se preparer a recevoir connections

#include <sys/socket.h>

int listen(int sockfd, int backlog);

I sockfd : socket publie, en attente de demandes de connectionsI backlog : nombre maximum de connections en attente permises

Creer nouveau socket anonyme pour nouvelles connections

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr* addr,

socklen_t* addrlen);

I sockfd : socket publie (bind et listen) avec connections en attenteI addr : identite du clientI Retourne descripteur de fichier du socket anonyme de la nouvelle connexion

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 69 / 76

Page 70: Systèmes d'exploitation et programmation concourante

Transmettre des donnees avec sockets Unix

Ouvrir une connexion client

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr* addr, socklen_t len);

Transmettre des donnees

#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

Alternativement, on peut utiliser version de lecture/ecriture de fichiers

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

ssize_t write(int fd, const void *buf, size_t count);

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 70 / 76

Page 71: Systèmes d'exploitation et programmation concourante

Signaux

Signaux : interruptions logicielles pour gerer evenements asynchronesI Concept important de Unix pour communication inter processus

Reception d’un signal par un processusI SE interrompt execution normale du processus et traite le signalI Actions de traitement possible

F Ignorer le signalF Intercepter le signal et executer routine de gestion du programmeF Executer routine par defaut

I Pour quelques signaux, routine de gestion non modifiables

Chaque signal a un nom et un entier associeI SIGINT (2) : interrompre le programme (ex. via CTRL-C dans le terminal)I SIGSEGV (11) : acces memoire a adresse invalideI SIGCHLD (20) : etat du processus enfant a change

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 71 / 76

Page 72: Systèmes d'exploitation et programmation concourante

Transmettre signal

Transmettre signal dans terminal : commande kill

$ kill -s TERM pid

Appel de fonction pour transmettre signal

#include <signal.h>

int kill(pid_t pid, int sig);

I Si pid=0, signal envoye aux processus du groupe courant (processus enfants)I Si pid=-1, signal envoye a tous les processus de l’utilisateur, excepte le processus courantI Autrement, signal envoye au processus pidI Si sig=0, verifie si processus courant peut signaler selon pid

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 72 / 76

Page 73: Systèmes d'exploitation et programmation concourante

Intercepter signal

Modifier routine de gestion de signal

#include <signal.h>

struct sigaction {

void (*sa_handler)(int);

void (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t sa_mask;

int sa_flags;

};

int sigaction(int signum,

const struct sigaction *act,

struct sigaction *oldact);

I signum : signal dont routine de gestion est modifieeI act : routine de gestion a utiliser

F sigaction.sa_handler : pointeur de fonction a utiliser

I oldact : si different de NULL, retourne ancienne routine de gestion

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 73 / 76

Page 74: Systèmes d'exploitation et programmation concourante

Exemple : modifier routine de gestion de signal

1 #include <stdio.h>

2 #include <unistd.h>

3 #include <signal.h>

4

5 static void sighdl(int sig) {

6 printf("Signal %d received\n", sig);

7 }

8

9 int main (int argc, char *argv[]) {

10 struct sigaction act;

11 memset(&act, '\0', sizeof(act));

12 act.sa_handler = &sighdl;

13 if(sigaction(SIGTERM, &act, NULL) < 0)

14 err_sys("sigaction failed!");

15 while(1) sleep(10);

16 return 0;

17 }

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 74 / 76

Page 75: Systèmes d'exploitation et programmation concourante

Autres elements sur signaux

Ignorer signal

act.sa_handler = SIG_IGN;

Utiliser signal par defaut

act.sa_handler = SIG_DFL;

Fonctions reentrantesI Fonction de gestion peut etre appelee a tout momentI Seules fonctions reentrantes doivent etre appelees

Signaux non gerablesI Routines pour signaux SIGKILL et SIGSTOP non modifiables, car geres par SE

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 75 / 76

Page 76: Systèmes d'exploitation et programmation concourante

Quelques signaux courants

Signal Numeros Action DescriptionSIGINT 2 Term Interruption de clavier (CTRL-C)SIGQUIT 3 Core Quitter du clavier (CTRL-\)SIGILL 4 Core Instruction illegaleSIGABRT 6 Core Signal de abort(3)SIGFPE 8 Core Exception a virgule flottanteSIGKILL 9 Term Tuer processus (non modifiable)SIGSEGV 11 Core Reference memoire invalide

SIGPIPE 13 Term Ecrire sur un pipe sans lecteurSIGALRM 14 Term Signal de alarm(2)SIGTERM 15 Term Signal de terminaisonSIGUSR1 30,10,16 Term Signal defini par l’utilisateur 1SIGUSR2 31,12,17 Term Signal defini par l’utilisateur 2SIGCHLD 20,17,18 Ign Processus enfant arrete ou termineSIGCONT 19,18,25 Cont Continue si arreteSIGSTOP 17,19,23 Stop Arreter processus (non modifiable)

SETR – GIF-3004 (U. Laval) SE et programmation concourante C. Gagne 76 / 76