Veuillez expliquer les points de vue de Linux et de Windows.
Je programme en C#, ces deux termes peuvent-ils faire une différence ? Veuillez poster autant que vous le pouvez, avec des exemples et tels.....
Merci
Veuillez expliquer les points de vue de Linux et de Windows.
Je programme en C#, ces deux termes peuvent-ils faire une différence ? Veuillez poster autant que vous le pouvez, avec des exemples et tels.....
Merci
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 certaine surcharge.
Les sections critiques ne peuvent être utilisées qu'au sein d'un seul processus, mais ont l'avantage de ne passer en mode noyau qu'en cas de contention - Les acquisitions non-contenues, qui devraient être le cas courant, sont incroyablement rapides. En cas de contention, elles entrent dans le noyau pour attendre une primitive de synchronisation (comme un événement ou un sémaphore).
J'ai écrit une application d'exemple rapide qui compare le temps entre les deux. Sur mon système, pour 1.000.000 d'acquisitions et de libérations involontaires, un mutex prend plus d'une seconde. Une section critique prend ~50 ms pour 1 000 000 d'acquisitions.
Voici le code de test, je l'ai exécuté et j'ai obtenu des résultats similaires si le mutex est premier ou deuxième, donc nous ne voyons pas d'autres effets.
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);
D'un point de vue théorique, un section critique est un morceau de code qui ne doit pas être exécuté par plusieurs threads à la fois parce que le code accède à des ressources partagées.
A mutex est un algorithme (et parfois le nom d'une structure de données) qui est utilisé pour protéger les sections critiques.
Sémaphores et Moniteurs sont des implémentations courantes d'un mutex.
En pratique, il existe de nombreuses implémentations de mutex disponibles dans Windows. Ils se distinguent principalement par leur niveau de verrouillage, leur portée, leurs coûts et leurs performances en fonction du niveau 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.
Le site lock(object)
est mis en œuvre en utilisant un Monitor
- voir MSDN pour référence.
Ces dernières années, de nombreuses recherches ont été menées sur synchronisation non-bloquante . L'objectif est de mettre en œuvre des algorithmes sans verrou ou sans attente. Dans de tels algorithmes, un processus aide d'autres processus à terminer leur travail afin que le processus puisse finalement terminer le sien. En conséquence, un processus peut terminer son travail même si 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.
En plus des autres réponses, les détails suivants sont spécifiques aux sections critiques de Windows :
InterlockedCompareExchange
opérationSous Linux, je pense qu'il existe un "spin lock" qui a un rôle similaire à celui de la section critique avec un compteur de rotation.
La section critique et le mutex ne sont pas spécifiques au système d'exploitation, ce sont des concepts de multithreading/multiprocessing.
Section critique C'est un morceau de code qui ne doit être exécuté que par lui-même à un moment donné (par exemple, il y a 5 threads qui tournent 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 tableau en même temps. 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* Le 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 de la section critique).
Un mutex est un objet qu'un thread peut acquérir, empêchant les autres threads de l'acquérir. Il est consultatif et non obligatoire ; un thread peut utiliser la ressource que le mutex représente sans l'acquérir.
Une section critique est une longueur de code qui est garantie par le système d'exploitation de ne pas être interrompue. En pseudo-code, ce serait comme :
StartCriticalSection();
DoSomethingImportant();
DoSomeOtherImportantThing();
EndCriticalSection();
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.