je reposte mon header qui permet de gérer des thread sout linux et windows.
#ifndef MY_THREAD_H
#define MY_THREAD_H
//Ces macros servent à uniformiser certaines fonctionnalités entre Windows et Linux.
#ifdef WIN32 //macro version Windows
# include <windows.h>
//definition des threads
# define callback_t unsigned long __stdcall
# define thread_t HANDLE*
# define thread_create(thrd, fct, param) thrd = new HANDLE;\\
*(thrd) = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(fct),(param),0,NULL)
# define thread_delete(thrd) CloseHandle(*(thrd));\\
delete (thrd);
# define thread_wait_close(thrd) WaitForMultipleObjects(1, *thrd, TRUE, INFINITE)
//definition des semaphores et mutex
# define mutex_t CRITICAL_SECTION
# define mutex_init(mutex) InitializeCriticalSection((mutex))
# define mutex_lock(mutex) EnterCriticalSection((mutex))
# define mutex_unlock(mutex) LeaveCriticalSection((mutex))
# define mutex_delete(mutex) DeleteCriticalSection((mutex))
# define semaphore_t HANDLE
# define semaphore_init(sema, max, place) ((sema) = CreateSemaphore(NULL, (max), (place), NULL))
# define semaphore_lock(sema) WaitForSingleObject((sema), INFINITE)
# define semaphore_unlock(sema) ReleaseSemaphore((sema), 1, NULL)
# define semaphore_delete(sema) CloseHandle(sema)
#else //macro version Linux
//definition des threads
# include <pthread.h>
# define callback_t void *
# define thread_t pthread_t*
# define thread_create(thrd, fct, param) (thrd) = new pthread_t;\\
pthread_create((thrd), NULL, (fct), (param))
# define thread_delete(thrd) delete (thrd);
# define thread_wait_close(thrd) pthread_join(*thrd, NULL)
//definition des semaphores et mutex
# include <semaphore.h>
# define mutex_t pthread_mutex_t *
# define mutex_init(mutex) (mutex) = new pthread_mutex_t;\\
pthread_mutex_init ((mutex), NULL)
# define mutex_lock(mutex) pthread_mutex_lock((mutex))
# define mutex_unlock(mutex) pthread_mutex_unlock((mutex))
# define mutex_delete(mutex) pthread_mutex_destroy((mutex));\\
delete ((mutex))
# define semaphore_t sem_t*
# define semaphore_init(sema, max, place) (sema) = new sem_t;\\
sem_init ((sema), (max), (place))
# define semaphore_lock(sema) sem_wait((sema))
# define semaphore_unlock(sema) sem_post((sema))
# define semaphore_delete(sema) sem_destroy((sema));\\
delete ((sema))
#endif
#endif
Pour commencer un thread est un outils capable de lancer des exécution parallèles de code dans un même programme.
________________
| |
| Code Principal |
|________________|
|
intruction...
| ________________
| | |
execution du thread -> | Code du thread |
| |________________|
| |
| |
intruction... intruction...
| |
| |
|-----------------------|
|
Fin du prog
Comme le dit l'autre tuto les thread sont à éviter tant qu'une exécution séquentiel est possible.
Mais pour un moteur 3d je dirais qu'ils sont conseillés surtout si il y a un moteur physique.
Je m'explique vous avez remarqué que les processeurs récents on tous des dual-corps. Et bien chaque thread s'exécute sur un corps différent se qui permet un gain énorme en performance.
Bien sur les threads ne sont pas a utilisés à la légère a cause des ressources critiques. Vous avez bien plusieurs processeurs mais qu'une seul Mémoire RAM. Et si 2 threads tentent d'accéder à la même partie de la mémoire et bien il risque de ne pas avoir les résultats voulus. Et même de faire planter le programme.
Je ne vais pas vous faire un court sur les risques des ressources critiques et vous demande de me croire sur parole que ceci est très dangereux pour un programme fiable.
Pour éviter de rentrer a plusieurs dans une zone critique il existe des fonctions de mise en attente. Les mutexs et le semaphores. Vous me dites "Je peux le faire moi même avec une variable global booléenne" Mais je vous répond que non car imaginé que pendant que vous tester votre variable et que vous changer d'état la variable, le processeur permute de thread. Vous risquez de rentrer à deux dans la zone critique et la de planter ou créer des erreurs dans votre programme.
Voici un petit programme simple avec l'utilisation des mutexs.
#include <iostream>
#include "mythread.h"
//creation du mutex
mutex_t mut;
mutex_t io;
void trace(int x)
{
//Vue que trace est appeler par un thread
//et qu'elle utilise les entrers sorties
//il faut utiliser un autre mutex
//ATTENTION voici la zone critique seule un thread à le droit
//d'utiliser l'ES
mutex_lock(io);
printf("x = %d\
", x);
mutex_unlock(io);
//Fin de zone critique
//un thread en file d'attente peut rentrer
return;
};
callback_t maFonc(void* x)
{
//recastage de x
int* intX = (int*)
//ATTENTION voici la zone critique seule un thread à le droit
// de modifier la veleur de X
mutex_lock(mut);
//multiplication de x par lui même
*intX = *intX * *intX;
mutex_unlock(mut);
//Fin de zone critique
//un thread en file d'attente peut rentrer
trace(*intX);
return NULL;
};
int main()
{
//Création de x
int x;
//initialisation du mutex
mutex_init(mut);
mutex_init(io);
//Creation des threads
thread_t thrd[10];
int i;
for(i = 0; i < 10; i++)
thread_create(thrd[i], maFonc, &x);
//attente de la fermeture des threads
for(i = 0; i < 10; i++)
thread_wait_close(thrd[i]);
//destruction des threads et du mutex
for(i = 0; i < 10; i++)
thread_delete(thrd);
mutex_delete(mutex);
mutex_delete(io);
printf("\
\
X Final = %d\
", x);
return 0;
};
Par contre il y a une règle de syntaxe qui ne va pas dans se programme. Il est important de s'imposer que seul les fonctions callback et celle qui créer le thread doivent utiliser des mutexs. deonc le code serait mieux ainsi:
#include <iostream>
#include "mythread.h"
//creation du mutex
mutex_t mut;
void trace(int x)
{
printf("x = %d\
", x);
return;
};
callback_t maFonc(void* x)
{
//recastage de x
int* intX = (int*)
//ATTENTION voici la zone critique seule un thread à le droit
// de modifier la veleur de X
mutex_lock(mut);
//multiplication de x par lui même
*intX = *intX * *intX;
trace(*intX);
mutex_unlock(mut);
//Fin de zone critique
//un thread en file d'attente peut rentrer
return NULL;
};
int main()
{
//Création de x
int x;
//initialisation du mutex
mutex_init(mut);
//Creation des threads
thread_t thrd[10];
int i;
for(i = 0; i < 10; i++)
thread_create(thrd[i], maFonc, &x);
//attente de la fermeture des threads
for(i = 0; i < 10; i++)
thread_wait_close(thrd[i]);
//destruction des threads et du mutex
for(i = 0; i < 10; i++)
thread_delete(thrd);
mutex_delete(mutex);
printf("\
\
X Final = %d\
", x);
return 0;
};
Pour finir les semaphores.
Je ne vais pas poster de code car il fonctionne comme les mutexs. À la seul différence c'est que, dans le create_semaphore, 'max' représente le nombre maximum de thread qui on le droit de rentrer dans la zone critique.
Et place est le nombre au quels sont déjà rentrer dans le semaphore.
je mexplique:
create_semaphore(sema, 10, 2);
10 processus auront le droit de rentrer dans le semaphore mais comme place = 2 seulement 8 pourront après l'initialisation. Donc si on fait un ...
create_semaphore(sema, 10, 10);
Aucun thread ne pourra rentrer dans la zone critique tant que l'on n'a pas fait un semaphore_unlock.
Astuce: create_semaphore(sema, 1, 0); est donc un mutex
- --------------------------------------------------------------------------------------
PS : Je ne dit pas que cet header est parfait et sans bug mais je l'utilise personnellement et je n'est jamais eu un seul bug dessus.
Voilà à vos questions