1 processus et threads. 2 implémentation des processus différent champs dune entrée de la table...

43
1 Processus et threads

Upload: bernarde-le-roux

Post on 04-Apr-2015

110 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

1

Processus et threads

Page 2: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

2

Implémentation des processus

Différent champs d’une entrée de la table des processus

Page 3: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

3

Création de processus sur UNIX

// Crée une copie exacte du processus appelant

pid_t fork(void)

// Remplace l’image du processus appelant

int execv(

const char *fichier,

char * const argv []

);

Page 4: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

4

Valeur de retour

#include <sys/types.h> #include <sys/wait.h>

pid_t wait(int *status)

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

Page 5: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

5

Création de processus sur Windows (1)

BOOL WINAPI CreateProcess( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation

);

Page 6: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

6

Création de processus sur Windows(2)

typedef struct _PROCESS_INFORMATION {HANDLE hProcess;HANDLE hThread;DWORD dwProcessId;DWORD dwThreadId;

} *LPPROCESS_INFORMATION;

Page 7: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

7

Fin d’exécution d’un processus

Conditions de fin d’exécution:

1. Sortie normale (volontaire)

2. Sortie avec erreur (volontaire)

3. Erreur fatale (involontaire)

4. Tué par un autre processus (involontaire)

Page 8: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

8

L’état d’un processus

• États possibles– en cours d’exécution– bloqué– prêt– etc.

• Transitions entre les états

Page 9: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

9

L’état d’un processus

Wikipedia

Page 10: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

10

Les threads (1)

(a) Trois processus possédant un seul thread.(b) Un processus possédant trois threads.

Page 11: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

11

Les threads (2)

• Items partagés par tous les threads d’un processus• Items à chaque thread

Page 12: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

12

Les threads (3)

Chaque thread possède sa propre pile.

Page 13: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

13

Utilisation des threads (1)

Un logiciel de traitement de texte avec trois threads

Page 14: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

14

Les threads POSIX

#include <pthread.h>

int pthread_create(

pthread_t *thread,

const pthread_attr_t *attr,

void *(*start_routine)(void*),

void *restrict arg);

void pthread_exit(void *value_ptr);

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

Page 15: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

15

Les threads POSIX

Certaines implémentations possèdent l’instruction:

void pthread_yield(void);

ou

void sched_yield(void);

Sur Solaris et Linux on compile avec l'option:

-lpthread

Page 16: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

16

Les threads sur Windows

HANDLE WINAPI CreateThread(

__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,

__in SIZE_T dwStackSize,

__in LPTHREAD_START_ROUTINE lpStartAddress,

__in_opt LPVOID lpParameter,

__in DWORD dwCreationFlags,

__out_opt LPDWORD lpThreadId );

VOID WINAPI ExitThread( __in DWORD dwExitCode);

Page 17: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

17

Les threads sur Windows

DWORD WINAPI WaitForSingleObject(

__in HANDLE hHandle,

__in DWORD dwMilliseconds );

DWORD WINAPI WaitForMultipleObjects(

__in DWORD nCount,

__in const HANDLE *lpHandles,

__in BOOL bWaitAll,

__in DWORD dwMilliseconds );

Page 18: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

18

Trois points importants:

• Comment partager les ressources?

• Concurrence pour l'utilisation des ressources

• Synchronisation

Communication interprocessus

Page 19: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

19

1. A voit que la prochaine case disponible est 7 puis est remplacé par B

2. B voit que la prochaine case disponible est 7, y place le nom de son fichier, puis est remplacé par A

3. A place le nom de son fichier dans une case qu’il croit libre écrasant le nom donné par B

Conditions de concurrence

Deux processus veulent accéder à la mémoire partagée en même temps.

Par exemple: Les processus A et B veulent utiliser la file d’impression.

Page 20: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

20

Sections Critiques (1)

L’exclusion mutuelle est une méthode qui permet de s’assurer que si un processus utilise une variable ou un fichier partagé, les autres processus seront exclus de la même activité.

Une section critique (ou région critique) est la partie du programme à partir de laquelle on accède à la mémoire partagée.

Page 21: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

21

Sections Critiques (2)

Quatre conditions pour obtenir l'exclusion mutuelle:1. Un seul processus à la fois dans la section critique

2. Aucune supposition sur le nombre et la vitesse des CPUs

3. Aucun processus hors de la section critique ne peut bloquer un autre processus.

4. Aucun processus ne doit attendre indéfiniment pour entrer en section critique.

Page 22: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

22

Sections critiques (3)

Exclusion mutuelle à l'aide des sections critiques.

Page 23: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

23

Solutions à l’exclusion mutuelle

• Variable de verrou • Un processus peut entrer seulement si VERROU=0 Il met alors VERROU=1 pour empêcher les autres processus d’entrer• Cette solution ne fonctionne pas sans aide matérielle

Page 24: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

24

L'instruction TSL (Test and Set Lock)

TSL R, LOCK est une opération atomique équivalente à:R=LOCK

LOCK=1

enter_region: TSL REGISTER,LOCK | copie lock dans le registre et le définit à 1 CMP REGISTER,#0 | lock était-il à 0 ? JNE enter_region | s'il n’était pas à 0, boucle RET | retourne à l’appelant ; entre en section critique

leave_region: MOVE LOCK,#0 | stocke un 0 dans lock RET | retourne à l’appelant

Page 25: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

25

L'instruction XCHG (Intel x86)

XCHG R, LOCK échange le contenu de R et LOCK

Cette instruction peut facilement remplacer TSL

enter_region: MOVE REGISTER, #1 | Mettre 1 dans REGISTER XCHG REGISTER,LOCK | Échanger REGISTER et LOCK CMP REGISTER,#0 | lock était-il à 0 ? JNE enter_region | s'il n’était pas à 0, boucle RET | retourne à l’appelant ; entre en section critique

leave_region: MOVE LOCK,#0 | stocke un 0 dans lock RET | retourne à l’appelant

Page 26: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

26

Opérations Sleep et Wakeup (1)

Alternative aux solutions par attente active vues jusqu’à présent.

Ex. Problème du producteur-consommateur

#define N 100 /* nombre de connecteurs dans le tampon */int count = 0;  /* nombre d’éléments dans le tampon */void producteur(void){ int item; while (TRUE) { item = produire_item( );  /* génère l’élément suivant */ if (count == N) sleep( );  /* si le tampon est plein, entre en sommeil */ ajouter_item(item);  /* place l’élément dans le tampon */ count = count + 1;  /* incrémente le décompte des éléments dans le tampon */ if (count == 1) wakeup(consommateur);  /* le tampon était vide ? */ }}

Page 27: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

27

Opérations Sleep et Wakeup (2)

void consommateur(void){ int item; while (TRUE) { if (count == 0) sleep( );  /* si le tampon est vide, entre en sommeil */ item = enlever_item( );  /* prélève un élément dans le tampon */ count = count - 1;  /* décrémente le décompte des éléments dans le tampon */ if (count == N - 1) wakeup(producteur);  /* le tampon était plein ? */ utiliser_item(item);  /* utilise l’élément */ }}

Que se passe-t-il si le producteur fait un wakeup entre le moment ou le consommateur constate que le tampon est vide et celui où il appelle sleep?

Page 28: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

28

Les sémaphores: opérations Up et Down (1)

Solution de Dijkstra au problème des wakeup perdus.

Un sémaphore est une variable partagée entre plusieurs processus et munie de deux nouvelles instruction atomiques:

Down(S): if (S==0) sleep S=S-1 Up(S): S=S+1 if (S==1) wakeup() // si des processus sont endormis sur le // sémaphore S alors l’un d’eux sera réveillé

Page 29: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

29

Les sémaphores

#define N 100 /* nombre d’emplacements dans le tampon */typedef int semaphore;  /* les sémaphores sont un type de variable int spécial */semaphore mutex = 1;  /* contrôle l’accès à la section critique */semaphore empty = N;  /* compte les emplacements vides dans le tampon */semaphore full = 0;  /* compte les emplacements pleins */

void producer(void){ int item; while (TRUE) { item = produce_item( ); /* génère quelque chose à placer dans le tampon */ down(&empty);  /* décrémente le décompte des emplacements vides */ down(&mutex);  /* entre en section critique */ insert_item(item);  /* place un nouvel élément dans le tampon */ up(&mutex);  /* quitte la section critique */ up(&full);  /* incrémente le décompte des emplacements pleins */ }}

Résolution au problème du producteur-consommateur.On utilise trois sémaphores:

Page 30: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

30

Les sémaphores

void consumer(void){ int item; while (TRUE) { down(&full);  /* décrémente le décompte des emplacements pleins */ down(&mutex);  /* entre en section critique */ item = remove_item();  /* prélève un élément dans le tampon */ up(&mutex);  /* quitte la section critique */ up(&empty);  /* incrémente le décompte des emplacements vides */ consume_item(item);  /* fait quelque chose avec l’élément */ }}

Page 31: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

31

Sémaphores sur Windows

HANDLE WINAPI CreateSemaphore(LPSECURITY_ATTRIBUTES lpsa, LONG lInitialCount, // Nombre de ressources initialement disponiblesLONG lMaximumCount, // Nombre maximale de ressourcesLPCTSTR lpName

);

DWORD WINAPI WaitForSingleObject(HANDLE hSemaphore,DWORD dwMilliSeconds // Peut être INFINITE

);

BOOL WINAPI ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, // Nombre de ressources à remettreLPLONG lpPreviousCount // Reçoit le nombre de ressource actuelle);

Page 32: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

32

Sémaphores sur Solaris#include <semaphore.h>

sem_t *sem_open(char* nom, // Le premier caractère du nom doit être '/'int oflag // O_CREAT ou O_CREAT | O_EXCLint mode // bits de permissionint valeur // valeur initiale

);

int sem_wait(sem_t *psem)

int sem_post(sem_t *psem)

int sem_init( // sémaphore sans nomsem_t * psem, int pshare, // Si non nul, peut être partagé avec d'autres processus int valeur // NULL = Attributs par défaut

);

Page 33: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

33

Sémaphores sur Solaris

#include <semaphore.h>

main() { sem_t my_semaphore; int rc; rc = sem_init(&my_semaphore, 0, 10); …}

Page 34: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

34

Les mutex

Les mutex sont des sémaphore qui ne peuvent prendre que la valeur 0 ou 1. Ils servent à réaliser l’exclusion mutuel.

Page 35: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

35

Mutex sur Solaris

#include <pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int pthread_ mutex_lock(pthread_mutex_t* pm);

int pthread_mutex_unlock(pthread_mutex_t* pm);

int pthread_mutex_init( // mutex dynamiquepthread_mutex_t * pm, const pthread_mutexattr_t *mattr // NULL = Attributs par défaut

);

Page 36: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

36

Mutex sur Windows

HANDLE WINAPI CreateMutex (LPSECURITY_ATTRIBUTES lpma, // Pour nos applications ce paramètre

// peut être mis à NULLBOOL bInitialOwner, // True pour créer et posséder le mutexLPTSTR lpName // Nom pour partager le mutex avec d'autres processus

// ( Peut être NULL));

DWORD WINAPI WaitForSingleObject(HANDLE hMutext,DWORD dwMilliSeconds // Peut être INFINITE

);

BOOL WINAPI ReleaseMutex( HANDLE hMutex );

Page 37: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

37

Critical Section sur Windowsvoid WINAPI InitializeCriticalSection(

LPCRITICAL_SECTION lpCriticalSection );

void WINAPI EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection

);

BOOL WINAPI InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION lpCriticalSection,

DWORD dwSpinCount );

void WINAPI LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection

);

Page 38: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

38

Critical Section sur Windows// Variable globaleCRITICAL_SECTION CriticalSection;

DWORD WINAPI ThreadProc( LPVOID lpParameter ){ ...EnterCriticalSection(&CriticalSection); ... // Accès à la ressource partagée.LeaveCriticalSection(&CriticalSection); ...}

void main(){ ... InitializeCriticalSection(&CriticalSection) ... // Création des threads DeleteCriticalSection(&CriticalSection) ... }

Page 39: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

39

Variables conditionelles

Permet à un thread de se bloquer non pas à l’entrée d’une région critique mais en fonction d’une certaine condition

définie par la valeur d’une variable.

Ex. Plusieurs threads se partage une variable P qu’ils incrémentent à tour de rôle.

Un des threads veut se bloquer tant que P n’aura pas pas

atteint une certaine valeur.

Page 40: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

40

Variables conditionelles sur Windows Vista

VOID WINAPI InitializeConditionVariablePCONDITION_VARIABLE cond

);

BOOL WINAPI SleepConditionVariableCS( // De façon atomique, bloque etPCONDITION_VARIABLE cond, // relâche la section critiquePCRITICAL_SECTION pcs,DWORD millisecond

);

VOID WINAPI WakeConditionVariable( // Débloque un thread bloquéPCONDITION_VARIABLE cond // sur la variable de condition

);

VOID WINAPI WakeAllConditionVariable( // Débloque tous les threads bloqués

PCONDITION_VARIABLE cond // sur la variable de condition );

Page 41: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

41

Variables conditionelles sur Solarispthread-cond_t cond = PTHREAD_COND_INITIALIZER;

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex

);

int pthread-cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

int pthread_cond_init( pthread_cond_t *cond,const pthread_condattr_t *attr

);

Page 42: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

42

Les barrières

• Utilisation des barrières– Les processus s'approchent de la barrière– Tous les processus sauf un sont bloqués– Le dernier processus arrive, libérant les autres

Page 43: 1 Processus et threads. 2 Implémentation des processus Différent champs dune entrée de la table des processus

43

Les barrières sur Solaris

int pthread_barrier_init(pthread_barrier_t * barrier, const pthread_barrierattr_t * attr, unsigned count);

int pthread_barrier_wait(pthread_barrier_t *barrier);

int pthread_barrier_destroy(pthread_barrier_t *barrier);