Vous êtes sur la page 1sur 39

Programmation multitâche

sous unix

Groupe Isaip-Esaip
P. Trégouët – A. Schaal

remerciements à M. Benzaïd
pour sa contribution à la rédaction de ce document

Isaip-Esaip Programmation multitâche sous Unix 1 02/11/06


PLAN

Processus
Signaux
Tubes entre processus de filiation commune
Tubes nommés entre processus de filiation différente
File de messages
Segments de mémoire partagée
Sémaphores
Sockets

Isaip-Esaip Programmation multitâche sous Unix 2 02/11/06


Livre de référence

Programmation
système en C
sous Linux

Auteur : Christophe Blaess


Édition EYROLLES

Isaip-Esaip Programmation multitâche sous Unix 3 02/11/06


Processus
Un processus est un programme en cours d’exécution
Un système multi-utilisateurs peut exécuter le même programme
sous plusieurs processus, pour plusieurs utilisateurs
L'espace mémoire alloué à un processus est constitué :
du Code du programme en cours d’exécution (segment code ou segment text)
des Données manipulées par le programme (segment data)
du Descripteur du processus (informations relatives au processus, pile
d’exécution,…)

Types d’informations : <unistd.h> Primitives

pid_t PID : numéro de processus, pid_t getpid(void)


pid_t PPID: numéro de processus parent, pid_t getppid(void)
uid_t UID : numéro de l’utilisateur réel, uid_t getuid(void)
uid_t EUID:numéro de l’utilisateur effectif, uid_t getuid(void)
etc.

Isaip-Esaip Programmation multitâche sous Unix 4 02/11/06


Manipulation des processus (1)
Création ou duplication de processus
pid_t fork(void)
La valeur retournée est le pid du fils pour le processus père, ou 0
pour le processus fils. La valeur -1 est retournée en cas d'erreur.
Le fils hérite de presque tous les attributs du parent : segment code
(partagé, copié), segment data (copié), PID/PPID (modifiées),
signaux interceptés (conservés), descripteur de fichiers/tubes
ouverts (copiés), pointeurs de fichiers (partagés)

Terminaison de processus
void exit (int code_retour)

Attente de terminaison de processus enfant


pid_t wait (int * code _retour),
pid_t waitpid (pid_t pid_enfant, int * code_retour,
int options)

Isaip-Esaip Programmation multitâche sous Unix 5 02/11/06


Manipulation des processus (2)
Sommeil de processus
Unsigned int sleep (unsigned int nb_secondes)
Un signal reçu interrompt le sommeil du processus.
Le programme continue alors son exécution après l'appel de sleep().
La valeur retournée par sleep() est le nombre de secondes restantes

Recouvrement de processus = changement du programme


exécuté par un processus (exec)
modification de l’image (le segment de code) du processus courant
Toutes les variables de l’ancien programme sont perdues
Il n’est pas possible de revenir d’un exec. Les instructions qui suivent
exec ne seront exécutés que si exec échoue
Passage de valeurs : par les variables d’environnement ou les
paramètres du nouveau programme
Primitives correspondantes: exec{l|v}[e|p]  man 3 exec
 l : liste d’arguments : fournir la liste (char *arg0, char *arg1, …, 0)
 v : tableau d’arguments : fournir un pointeur sur le tableau (char ** argv avec
denier élément = ‘0’)
 Etc.

Isaip-Esaip Programmation multitâche sous Unix 6 02/11/06


Besoins de communication
entre processus
Deux processus peuvent éventuellement partager le
même code (ceci est sous le contrôle du système)
mais les espaces mémoires réservés aux variables
sont complètement étanches : un processus n'a aucun
accès aux variables d’un autre processus
On peut néanmoins créer une application multitâche et
avoir besoin de synchroniser ces tâches
ou d’échanger des informations entre ces tâches.
Les systèmes d’exploitations sont donc munis de
mécanismes appropriés
Synchronisation par signaux ou sémaphores
Communication de données par fichiers, tubes (pipes) files de
messages (queues ou boîtes à lettres) variables implantées
dans un segment de mémoire partagée

Isaip-Esaip Programmation multitâche sous Unix 7 02/11/06


Communications
locales ou distantes

Hôte Hôte 1 Hôte 2

Processus Processus Processus Processus


Utilisateur Utilisateur Utilisateur Utilisateur

Noyau du S.E Noyau S.E Noyau S.E

Communication intra-système Communication inter-systèmes

Réseau

Isaip-Esaip Programmation multitâche sous Unix 8 02/11/06


La communication par signaux (1)

Un signal peut être assimilé à une interruption logicielle


(par analogie avec les interruptions matérielles)
Comme pour une interruption matérielle, la réception
d'un signal interrompt le traitement en cours et
exécute automatiquement la fonction associée au
signal (programmation événementielle).

En langage C, l'association entre le numéro du signal


et la fonction est réalisé par un appel à la fonction
système signal().

Note : la fonction sigaction() peut être utilisée à la place de


signal(). Voir man sigaction.

Isaip-Esaip Programmation multitâche sous Unix 9 02/11/06


La communication par signaux (2)
Un signal est
Envoyé par un processus
Reçu par un autre processus (éventuellement le même)
Véhiculé par le noyau
Comment réagit un processus qui reçoit un signal ?
Il interrompt le traitement en cours
il exécute la fonction de traitement du signal
il reprend l'exécution du traitement interrompu

Si le processus était endormi, il est réveillé par le signal.


Après l'exécution de la fonction associée au signal,
dans le cas où il est réveillé avant la fin d'une temporisation il ne se rendort pas;
par contre s'il attendait la fin d'une entrée-sortie, il continue à attendre.
Comportement associée à la réception d'un signal :
En général un comportement par défaut est défini : Terminaison
anormale du processus (ex: violation de mémoire, division par zéro)
Le processus peut ignorer le signal
Le processus peut redéfinir, par une fonction spécifique, son
comportement à la réception d'un signal

Isaip-Esaip Programmation multitâche sous Unix 10 02/11/06


Origine des signaux
Frappe de caractères
touche signal

CTRL-C SIGINT
CTRL-\ SIGQUIT
CTRL-Z SIGSTP

Erreurs du programme
Violation de mémoire, SIGSEGV
Division par zéro, SIGFPE

Commande kill
Primitive système : kill(), alarm().

Isaip-Esaip Programmation multitâche sous Unix 11 02/11/06


Liste des signaux
demo@forum:~> kill -l

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL


5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 33) SIGRTMIN 34) SIGRTMIN+1
35) SIGRTMIN+2 36) SIGRTMIN+3 37) SIGRTMIN+4 38) SIGRTMIN+5
39) SIGRTMIN+6 40) SIGRTMIN+7 41) SIGRTMIN+8 42) SIGRTMIN+9
43) SIGRTMIN+10 44) SIGRTMIN+11 45) SIGRTMIN+12 46) SIGRTMIN+13
47) SIGRTMIN+14 48) SIGRTMIN+15 49) SIGRTMAX-15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX

Isaip-Esaip Programmation multitâche sous Unix 12 02/11/06


Signaux les plus fréquemment utilisés

1 SIGHUP terminaison du processus leader


2 SIGINT frappe d’interruption (CTRL-C)
3 SIGQUIT frappe de quit (CTRL-\)
4 SIGILL instruction illégale
6 SIGABRT problème matériel
7 SIGBUS erreur sur le BUS
8 SIGFPE erreur arithmétique
9 SIGKILL signal de terminaison
la réaction à ce signal ne peut être redéfinie
10 SIGUSR1 signal utilisateur
11 SIGSEGV violation écriture mémoire
12 SIGUSR2 signal utilisateur
13 SIGPIPE écriture sur un tube non ouvert en lecture
14 SIGALRM fin de temporisateur
15 SIGTERM terminaison normale d’un processus
17 SIGCHLD terminaison (arrêt) d’un fils
18 SIGCONT continuation d’un processus arrêté par SIGSTOP
19 SIGSTOP signal de suspension d’exécution de processus
20 SIGTSTP frappe du caractère de suspension sur le clavier (CTRL-Z)

Isaip-Esaip Programmation multitâche sous Unix 13 02/11/06


Envoi de signaux en langage C
#include <signal.h>
int kill(pid_t pid,int sig)
pid : > 0 : pid de processus destinataire
sig : le signal à envoyer

Envoie un signal à un processus

#include <unistd.h>
unsigned alarm (unsigned nb)

Envoie un signal SIGALRM au processus en cours dans nb secondes.

Attention :
ne pas mélanger l'utilisation de alarm et de sleep
qui partagent le même "timer" (voir man alarm)

Isaip-Esaip Programmation multitâche sous Unix 14 02/11/06


Préparer la réception des signaux en langage C
#include <signal.h>
void (*signal(int signum, void (*handler)(int)))(int);

signum : le signal à intercepter


handler : pointeur sur une fonction qui gère le signal
c'est simplement en C l'identificateur de cette fonction
ou constante correspondant à un comportement prédéfini:
SIG_DFL : comportement par défaut
SIG_IGN : ignorer le signal

#include<unistd.h>
int pause(void);

Endort le processus appelant jusqu'à ce qu'il reçoive un signal.

on peut aussi utiliser sleep() si on veut limiter l’attente

Isaip-Esaip Programmation multitâche sous Unix 15 02/11/06


Communication par signaux : exemple
#include<signal.h>

void standard(int numero)


{ printf("standard Signal %d recu : \n",numero);
}
void message(int numero)
{ printf("message Signal %d recu\n",numero);
}

main()
{int numero;
// traitements spécifiques
for (numero=1;numero<32;numero++)signal(numero,standard);
signal(SIGINT,message); signal(SIGQUIT,message);
//traitements prédéfinis
signal(1,SIG_DFL); signal(4,SIG_IGN);

// Rien à faire, sauf réagir aux signaux: attente passive


while (1) pause();
}
Isaip-Esaip Programmation multitâche sous Unix 16 02/11/06
Tubes : principe (1)
Un tube est traité comme un fichier ouvert
Il est transmis aux processus enfants de la même manière
que les fichiers ouverts
Un tube est cependant un fichier particulier :
Il n’a pas de nom dans l’arborescence des fichiers
Il est connu par deux descripteurs (lecture, écriture)
On lit/écrit dans un tube
comme on lit/écrit dans un fichier séquentiel
Utilisation des fonctions read et write
(éventuellement fscanf, fprintf etc…)
Les données ne sont pas structurées:
le pipe ne contient qu’une suite d’octets
Un tube est comme un "tuyau" avec une entrée et une sortie :
Plusieurs processus peuvent y écrire des données
Plusieurs processus peuvent y lire des données

Isaip-Esaip Programmation multitâche sous Unix 17 02/11/06


Tubes : principe (2)
Le fonctionnement est de type FIFO :
On lit toujours les octets dans l'ordre
où ils ont été déposés dans le tube
Il n’est pas possible de lire un octet
sans voir lu tous ceux qui le précèdent
Une donnée lue par un processus ne pourra
jamais être relue par un autre processus
Les droits d’accès sont du même genre que les droits
d’accès Unix sur les fichiers (rwx, rwx, rwx)
Si un tube est vide, ou si tous les descripteurs
susceptibles d’y écrire sont fermés, la primitive read()
renvoie la valeur 0 (fin de fichier atteinte).
Un processus qui écrit dans un tube qui n’a plus de
lecteurs (tous les descripteurs susceptibles de lire sont
fermés) reçoit le signal SIGPIPE

Isaip-Esaip Programmation multitâche sous Unix 18 02/11/06


TUBES : primitives utiles

Création :
#include <unistd.h>
int pipe(int p_desc[2])
p_desc[0] pour la lecture, p_desc[1] pour l’écriture

Entrées/Sorties :
write (p_desc[1], buf_ecrire, nbre_octets)
read (p_desc[0], buf_lire, nbre_octets)

FILE * fdopen():fprintf(), fscanf(),etc...


fflush : écrire la zone tampon dans le tube
avant qu’elle ne soit remplie

Pour éviter l’interblocage fermer le côté de tube non


utilisé, par la primitive close()

Isaip-Esaip Programmation multitâche sous Unix 19 02/11/06


TUBES : exemple
#include <signal.h>
main(){
int i, ret, p_desc[2];
char c;
pipe(p_desc);
write(p_desc[1],"AB",2);
close(p_desc[1]);
for (i=1; i<=4; i++) {
ret = read(p_desc[0],&c,1) ;
if (ret == 1) printf("valeur lue: %c\n",c) ;
else perror("impossible de lire dans le tube\n") ;
}
} Résultat de l’exécution :
valeur lue : A
valeur lue: B
impossible de lire dans le tube : Success
impossible de lire dans le tube: Illegal seek

Isaip-Esaip Programmation multitâche sous Unix 20 02/11/06


TUBES Nommés
Les tubes ordinaires, sont non visibles dans l’arborescence des
fichiers, et accessibles uniquement aux processus d’une même
affiliation

Tubes nommés : visibles dans l’arborescence de fichiers,


utilisables entre processus ne partageant pas la même filiation
Par contre, aucune information n’est enregistrée sur disque, le
transfert d’information s’effectue toujours en mémoire.
Primitives correspondantes :
int mknod(const char *nom_fich,mode_t mode, dev_t dev)
int mkfifo (const char *pathname, mode_t mode);
Ouverture de tube par les processus connaissant le nom du tube :
En lecture/écriture par open()
Par défaut, ouverture bloquante :
lecteurs et écrivains s’attendent  synchronisation

Isaip-Esaip Programmation multitâche sous Unix 21 02/11/06


Nommage des objets IPC
IPC = Inter Process Communication
Trois types d’objets IPC :
files de message,
segments de mémoire partagée
sémaphores
En général ces objets sont créés par un processus et utilisés par d’autres, sans qu’il y
ait de liens de parenté entre ces processus.
A chaque objet IPC sera associée une clé d’identification
de 8 chiffres hexadécimaux
Cette identification externe, définie au moment où on écrit le programme est
analogue à un nom de fichier : on crée ou on cherche un sémaphore d’une valeur
de clé donnée comme on ouvre un fichier de nom donné
Cependant, on ne peut prévoir si un autre programmeur n’a pas par hasard utilisé
la même clé pour un autre objet IPC dans une autre application multitâche. On
pourra donc utiliser une fonction spéciale, ftok(), pour créer une clé unique à partir
d’un nom de fichier existant dans le système de fichiers et d’un numéro de projet
(ceci n'est donc définit qu’au moment de l’exécution, sur une machine donnée).

# include <sys/ipc.h>
key_t ftok(const char *pathname,int proj_id);

Isaip-Esaip Programmation multitâche sous Unix 22 02/11/06


Constantes communes relatives
aux primitives IPC

Drapeaux :
IPC_CREAT : créer un objet s'il n’existe pas
IPC_EXCL : échouer si l'objet existe déjà
IPC_NOWAIT : ne pas attendre
IPC_PRIVATE : clé privée, pas de lien avec le système de
fichiers
Commandes :
IPC_RMID : suppression
IPC_SET : mise à jour des attributs
IPC_STAT : lecture des attributs
Permissions : Analogues à celles du système de fichiers UNIX

Isaip-Esaip Programmation multitâche sous Unix 23 02/11/06


Commandes de manipulation des objets IPC

ipcs : liste des objets ipc existants


ipcrm : suppression d’un objet ipc

mail:/home/demo # ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch statu
0x00000001 720896 root 600 33554432 6 dest
0x00000012 753665 root 600 262144 1 dest
0x00000034 819202 root 600 33554432 11 dest

------ Semaphore Arrays --------


key semid owner perms nsems
0x00000005 98304 wwwrun 600 1
0x00000006 131073 wwwrun 600 1

------ Message Queues --------


key msqid owner perms used-bytes messages
0x00001f58 0 root 600 0 0

Isaip-Esaip Programmation multitâche sous Unix 24 02/11/06


Files de messages : principe
Contrairement aux tubes une file de message contient des
données structurées composées
D’un type de message
D’un message de longueur variable
A la différence des pipes, il sera possible d’attendre uniquement
des messages d’un type donné: s’il n’y a que des messages
d’un autre type, le processus sera bloqué (attente passive)
Comme les pipes, les files de message sont gérées selon un
algorithme FIFO : on lit toujours le message du type cherché qui
a séjourné le plus longtemps dans la file
L’attente est par défaut bloquante, mais, comme pour les
pipes, et si cela est nécessaire, le processus peut ne pas
attendre en positionnant le drapeau IPC_NOWAIT. Il recevra
un code d’erreur lui indiquant s'il a ou non obtenu un message.
Comme les pipes, les files de messages ont des droits d’accès
de type Unix (rwx,rwx,rwx)

Isaip-Esaip Programmation multitâche sous Unix 25 02/11/06


Files de messages : primitives
Création :
int msgget(key_t key, int flg) : retour = msq_id
Emission : (bloquante si file pleine et flg ne contient pas IPC_NOWAIT)
int msgsnd(int msqid,struct msgbuf *msgp,int msgsz,int flg);
Avec struct msgbuf {long msgtyp; char * msgtext;}
Réception : (bloquante si file vide et flg ne contient pas IPC_NOWAIT)
int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
msgtyp = 0 : premier message lu
msgtyp > 0 : premier message de type msgtyp
msgtyp < 0 : premier message avec un type ≤ |msgtyp|
Opérations de contrôle :
int msgctl(int f_id, int cmde, struct msqid_ds *structure)
cmde = IPC_RMID, IPC_STAT, IPC_SET
msqid_ds : structure définie dans <sys/msg.h> qui donne des informations sur la
file comme les droits d’accès, le dernier processus écrivain,etc.

Isaip-Esaip Programmation multitâche sous Unix 26 02/11/06


Création d'une File de messages : exemple
#include <errno.h> printf("identificateur de
la file: %d\n",msqid);
#include <sys/types.h>
#include <sys/ipc.h>
printf("cette file est
#include <sys/msg.h> identifiée par la clé
#define ID 123 unique : %ld\n",
main() ftok(path,ID)) ;
{ }
int msqid ;

char *path = "nom_de_fichier_existant";

if (( msqid = msgget(ftok(path,ID),
IPC_CREAT|IPC_EXCL|MSG_R|MSG_W))
== -1)
{
perror("Echec de msgget"); Résultat de l’exécution :
exit(1); identificateur de la file: 700
} cette file est identifiée par la clé
unique : 2064941749

Isaip-Esaip Programmation multitâche sous Unix 27 02/11/06


Mémoire partagée
Un segment de mémoire partagé est un espace de mémoire dans
lequel un processus pourra "allouer" des variables accessibles par
des pointeurs.
Un processus crée un segment de mémoire partagée ou
demande à utiliser un segment déjà créé. (shmget)
Un processus (le même ou un autre) demande au système
d’initialiser un pointeur sur cet espace (shmat)
•Ce pointeur contiendra en fait une adresse de mémoire virtuelle
différente pour chaque processus -
•qui sera traduite au moment de l’exécution en adresse physique
identique pour tous les processus utilisant cette mémoire partagée.
L'adresse physique est inaccessible au programmeur.
L’accès à des variables définies dans un segment de mémoire
partagée nécessite en général une synchronisation rigoureuse
entre les processus: cette synchronisation sera réalisée le plus
souvent par des sémaphores
Aux segments de mémoire partagée sont associés des droits
d'accès de type Unix

Isaip-Esaip Programmation multitâche sous Unix 28 02/11/06


Mémoires partagées: primitives

Création :
int shmget(key_t key, int size, int flg) : retour = shm_id
Attachement :
int shmat(int shmid, const void *shmadr, int flg);

adr = 0  choix de l’adresse par le système d’exploitation


Une même région peut être attachée plusieurs fois à des adresses différentes
Retour : adresse d’attachement effective ou -1
Détachement :
int shmdt(const void *shmadr) : retour = 0 ou -1
Libération de l’espace mémoire uniquement lors du dernier détachement
Opérations de contrôle :
int shmctl(int shm_id,int cmde,struct shmid_ds *structure)
cmde = IPC_RMID, IPC_STAT, IPC_SET, SHM_(UN)LOCK (verrouillage
en mémoire = pas de swap autorisé)

Isaip-Esaip Programmation multitâche sous Unix 29 02/11/06


Mémoires partagées : exemple
#include <sys/types.h> pid =fork() ;
#include <sys/ipc.h> if(pid == 0){/*processus fils*/
#include <sys/shm.h> mem = shmat(shmid,0,flag);
#include <sys/wait.h>
#include <stdio.h> strcpy(mem,"Message pour le pere");
#include <string.h> shmdt(mem);
void main(){ }
int pid,shmid ; else {/*processus père*/
char *mem ; mem = shmat(shmid,0,flag) ;
int flag = 0 ;
key_t clef ; printf("message reçu de fils :
printf("donnez la clé:"); %s\n",mem);
scanf("%ld",&clef); shmdt(mem);
shmid = shmget(clef,100, }
IPC_CREAT|IPC_EXCL|SHM_R| wait(0) ;
SHM_W); shmctl(shmid,IPC_RMID,NULL)
printf("Identificateur du
segment est %d \n",shmid); }

Isaip-Esaip Programmation multitâche sous Unix 30 02/11/06


Pourquoi utiliser un
sémaphore ?
D'une manière générale, un sémaphore sert à la synchronisation
entre les processus
Un sémaphore utilisé pour l’exclusion mutuelle (garantir qu’un seul
processus accède à un moment donné à une variable partagée),
utilisera 2 primitives
Attendre l’accès exclusif à la ressource partagée : si la ressource est déjà
utilisée par un processus, le processus qui fait cette demande sera endormi
et mis dans une file d’attente de processus
Libérer l’accès exclusif à la ressource partagée : si la file d’attente des
processus attendant cette ressource est non vide, le processus qui a dormi
le plus longtemps est réveillé
La section de programme qui se trouve entre les 2 primitives attendre
la ressource et libérer la ressource s’appelle une section critique
Les sémaphores n’empêchent pas les processus d’accéder à une
ressource: un processus « qui ne respecterait pas la discipline» et
accéderait à la ressources sans attendre son tour pourrait le faire sans
aucune restriction
Aux sémaphores sont associés des droits d’accès de type Unix

Isaip-Esaip Programmation multitâche sous Unix 31 02/11/06


Le "mécanisme" des sémaphores

Sémaphore = objet composé :


une variable (la valeur du sémaphore)
une file d’attente (les processus bloqués attendant la ressource)
Primitives associées :
Initialisation (avec une valeur positive ou nulle)
Manipulation :
 Prendre (P ou Wait) = demande d’autorisation
 Vendre (V ou Signal) = fin d’utilisation
Principe : sémaphore associé à une ressource
Prendre = demande d’autorisation (puis-je utiliser la ressource?)
Si valeur > = 0 accord, sinon blocage
Vendre = restitution d’autorisation (je n'ai plus besoin de la ressource)
Si valeur < 0 déblocage d’un processus

Isaip-Esaip Programmation multitâche sous Unix 32 02/11/06


Sémaphores : exemple
Parking de N places contrôlé par un feu

Isaip-Esaip Programmation multitâche sous Unix 33 02/11/06


Sémaphores : algorithmes des primitives P et V

Initialisation(sémaphore,n)
valeur[sémaphore] = n

P(sémaphore)
valeur[sémaphore] = valeur[sémaphore] - 1
si (valeur[sémaphore] < 0) alors
étatProcessus = Bloqué
mettre processus en file d’attente
finSi
invoquer l’ordonnanceur
V(sémaphore)
valeur[sémaphore] = valeur[sémaphore] + 1
si (valeur[sémaphore] == 0) alors
extraire processus de file d’attente
étatProcessus = Prêt
finSi
invoquer l’ordonnanceur

Isaip-Esaip Programmation multitâche sous Unix 34 02/11/06


UNIX IPC : tableau de sémaphores (1)
Création ou attachement :
int semget(key_t clé,int nsems,int semflg) : retour = semid

Opérations sur le compteur de sémaphore :


int semop (int semid, struct sembuf *spos, int nsops)
Avec struct sembuf { u_short sem_num;
short sem_op;
short sem_flg; }
sem_op > 0 : La valeur du sémaphore est augmentée de sem_op.
"sem_op ressources sont rendues disponibles". Un ou plusieurs
processus bloqués pourront être libérés s'il y a suffisamment de
ressources. Analogue à V, le processus appelant n'est jamais bloqué.
sem_op = 0 : Teste si le sémaphore a la valeur 0. Si ce n'est pas le cas,
le processus est mis en attente de la mise à zéro du sémaphore.
"exemple : un écrivain attend que tous les lecteurs aient fini de lire"
sem_op < 0 : La valeur du sémaphore est diminuée de |sem_op|.
"le processus demande sem_op ressources". Si le résultat est nul,
tous les processus en attente de cet événement sont réveillés. Si le
résultat est négatif, le processus est bloqué "en attendant de disposer de
suffisamment de ressources".
Isaip-Esaip Programmation multitâche sous Unix 35 02/11/06
Sémaphores IPC (2)

Opérations de base : exlusion mutuelle


P(s) : semop(sem_num, -1, 0)
V(s) : semop(sem_num, +1, 0)

Opérations de contrôle :
int semctl(int semid,int semnum,int cmd,
union semun arg)
IPC_RMID, IPC_STAT, IPC_SET,
Commandes spécifiques aux sémaphore :
 GETVAL : retourne la valeur d’un sémaphore,
 GETPID : retourne le PID du processus effectuant dernière opération,
etc.

Isaip-Esaip Programmation multitâche sous Unix 36 02/11/06


Sockets
Les "sockets", ("prise" ou "connecteur" en anglais), fournissent une
interface de programmation qui permet de définir facilement un canal
de communication entre 2 processus locaux ou distants
Chaque extrémité d’un canal de communication, est définie par un numéro
de port
Un descripteur de socket est analogue à un descripteur de fichier
Mêmes primitives read et write que pour les fichiers
Communication bidirectionnelle (contrairement aux pipes)

Format machine 1 Format machine 2

processus processus
CLIENT SERVEUR
N°PORT 1 N°PORT 2
Adresse IP 1 Adresse IP 2

Socket Socket

Format réseau

Isaip-Esaip Programmation multitâche sous Unix 37 02/11/06


Communication en mode connecté (TCP)

socket() socket()

CLIENT bind() SERVEUR

listen()

connect() accept()

write()/ read()/
Send() Recv() Attente
Transfert de
nouvelle
données
read()/ write()/ connexion
Recv() Send()

close() close()

Isaip-Esaip Programmation multitâche sous Unix 38 02/11/06


Communication en mode non connecté (UDP)

socket() socket()

CLIENT bind() SERVEUR

Sendto() Recvfrom()
Transfert de
données
Recvfrom() Sendto()

close() close()

Isaip-Esaip Programmation multitâche sous Unix 39 02/11/06

Vous aimerez peut-être aussi