GNU/Linux >> Tutoriels Linux >  >> Linux

Quelle est la différence entre le mutex et la section critique ?

Critical Section et Mutex ne sont pas spécifiques au système d'exploitation, leurs concepts de multithreading/multiprocessing.

Section critique Est un morceau de code qui ne doit s'exécuter que par lui-même à un moment donné (par exemple, 5 threads s'exécutent simultanément et une fonction appelée "critical_section_function" qui met à jour un tableau ... vous ne voulez pas que les 5 threads mettent à jour le array à la fois. Ainsi, lorsque le programme exécute la fonction Critical_section_function(), aucun des autres threads ne doit exécuter sa fonction Critical_section_function.

mutex* Mutex est un moyen d'implémenter le code de la section critique (pensez-y comme un jeton... le thread doit en avoir la possession pour exécuter le code_section_critique)


Pour Windows, les sections critiques sont plus légères que les mutex.

Les mutex peuvent être partagés entre les processus, mais entraînent toujours un appel système au noyau, ce qui entraîne une surcharge.

Les sections critiques ne peuvent être utilisées qu'au sein d'un processus, mais ont l'avantage de ne basculer en mode noyau qu'en cas de conflit - Les acquisitions sans concurrence, ce qui devrait être le cas courant, sont incroyablement rapides. En cas de conflit, ils entrent dans le noyau pour attendre une primitive de synchronisation (comme un événement ou un sémaphore).

J'ai écrit un exemple d'application rapide qui compare le temps entre les deux. Sur mon système, pour 1 000 000 d'acquisitions et de libérations incontrôlées, un mutex prend plus d'une seconde. Une section critique prend environ 50 ms pour 1 000 000 acquisitions.

Voici le code de test, j'ai exécuté ceci et j'ai obtenu des résultats similaires si le mutex est le premier ou le deuxième, donc nous ne voyons aucun autre effet.

HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
CRITICAL_SECTION critSec;
InitializeCriticalSection(&critSec);

LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;

// Force code into memory, so we don't see any effects of paging.
EnterCriticalSection(&critSec);
LeaveCriticalSection(&critSec);
QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
    EnterCriticalSection(&critSec);
    LeaveCriticalSection(&critSec);
}

QueryPerformanceCounter(&end);

int totalTimeCS = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);

// Force code into memory, so we don't see any effects of paging.
WaitForSingleObject(mutex, INFINITE);
ReleaseMutex(mutex);

QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
    WaitForSingleObject(mutex, INFINITE);
    ReleaseMutex(mutex);
}

QueryPerformanceCounter(&end);

int totalTime = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);

printf("Mutex: %d CritSec: %d\n", totalTime, totalTimeCS);

En plus des autres réponses, les détails suivants sont spécifiques aux sections critiques sur Windows :

  • en l'absence de conflit, l'acquisition d'une section critique est aussi simple qu'un InterlockedCompareExchange opération
  • la structure de la section critique contient de la place pour un mutex. Il est initialement non alloué
  • s'il y a conflit entre les threads pour une section critique, le mutex sera alloué et utilisé. Les performances de la section critique se dégraderont à celles du mutex
  • si vous anticipez une forte contention, vous pouvez allouer la section critique en spécifiant un nombre de rotations.
  • s'il y a un conflit sur une section critique avec un nombre de rotations, le thread tentant d'acquérir la section critique tournera (attente occupée) pendant ce nombre de cycles de processeur. Cela peut entraîner de meilleures performances que la mise en veille, car le nombre de cycles pour effectuer un changement de contexte vers un autre thread peut être beaucoup plus élevé que le nombre de cycles pris par le thread propriétaire pour libérer le mutex
  • si le nombre de tours expire, le mutex sera alloué
  • lorsque le thread propriétaire libère la section critique, il est nécessaire de vérifier si le mutex est alloué, si c'est le cas, il définira le mutex pour libérer un thread en attente

Sous Linux, je pense qu'ils ont un "spin lock" qui sert un objectif similaire à la section critique avec un nombre de spins.


D'un point de vue théorique, une section critique est un morceau de code qui ne doit pas être exécuté par plusieurs threads à la fois car le code accède à des ressources partagées.

Un mutex est un algorithme (et parfois le nom d'une structure de données) utilisé pour protéger les sections critiques.

Les sémaphores et les moniteurs sont des implémentations courantes d'un mutex.

En pratique, de nombreuses implémentations de mutex sont disponibles dans Windows. Ils diffèrent principalement en conséquence de leur mise en œuvre par leur niveau de verrouillage, leurs portées, leurs coûts et leurs performances sous différents niveaux de contention. Voir CLR Inside Out -Utilisation de la concurrence pour l'évolutivité pour un tableau des coûts des différentes implémentations de mutex.

Primitives de synchronisation disponibles.

  • Surveiller
  • Mutex
  • Sémaphore
  • ReaderWriterLock
  • ReaderWriterLockSlim
  • Interverrouillé

Le lock(object) l'instruction est implémentée à l'aide d'un Monitor - voir MSDN pour référence.

Au cours des dernières années, de nombreuses recherches ont été menées sur la synchronisation non bloquante. L'objectif est d'implémenter des algorithmes sans verrou ni attente. Dans de tels algorithmes, un processus aide d'autres processus à terminer leur travail afin que le processus puisse enfin terminer son travail. En conséquence, un processus peut terminer son travail même lorsque d'autres processus, qui ont essayé d'effectuer un travail, se bloquent. En utilisant des verrous, ils ne libéreraient pas leurs verrous et empêcheraient les autres processus de continuer.


Linux
  1. Quelle est la différence entre les threads NPTL et POSIX ?

  2. Quelle est la différence entre fsck et e2fsck ?

  3. Quelle est la différence entre `su -` et `su --login` ?

  4. Quelle est la différence entre $(CC) et $CC ?

  5. Quelle est la différence entre unlink et rm ?

Quelle est la différence entre Linux et Unix ?

Quelle est la différence entre la connexion et le shell sans connexion

Quelle est la différence entre la commande apt et apt-get ?

Qu'est-ce qu'un Hyperviseur ? Quelle est la différence entre les types 1 et 2 ?

Quelle est la différence entre curl et Wget ?

Quelle est la différence entre ls et l ?