Question

La désignation de cette fonction semble que c'est des choses compliquées en cours. Quand exactement on ne sait que c'est la voie à suivre au lieu de faire quelque chose comme ceci:

Préparation     CRITICAL_SECTION cs;     int * p = malloc (sizeof (int)); // Site d'allocation     InitializeCriticalSection (& cs); // Hint de première écriture

Discussion # 1      {     * P = 1; // Écrire     }

Discussion # 2      {     EnterCriticalSection (& cs);     * P = 2; // Deuxième écriture     LeaveCriticalSection (& cs);     }

J'ai une écriture qui se fait dans un thread:

Run()
{
// some code
m_bIsTerminated = TRUE;
// some more code
}

Alors, j'ai une lecture qui se fait dans un autre thread (potentiellement en même temps):

Terminate()
{
// some code
if( m_bIsTerminated )
{
m_dwThreadId = 0;
m_hThread = NULL;
m_evExit.SetEvent();
return;
}
// even more code
}

Quelle est la meilleure solution pour résoudre cette condition de course? Sont des sections critiques la voie à suivre ou est l'utilisation de InterlockedExchangeAdd () plus utile?

Était-ce utile?

La solution

InterlockedExchangeAdd permet d'ajouter une valeur à un nombre entier comme une opération atomique, ce qui signifie que vous ne devez utiliser une section critique. Cela supprime également le risque d'une impasse si l'un de vos fils jette une exception -. Vous devez vous assurer que vous ne gardez pas de verrouillage de quelque nature que ce qui empêcherait les autres threads d'acquérir ce verrou

Pour votre scénario, vous pouvez certainement utiliser une fonction Interlocked ...-, mais j'utiliseriez un événement (CreateEvent, SetEvent, WaitForSingleObject), probablement parce que je me surprends souvent besoin d'attendre plus d'un objet (vous pouvez attendre pour zéro seconde dans votre scénario).

màj: L'utilisation volatile pour la variable peut fonctionner, mais il n'est pas recommandé, voir: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html et http://www-949.ibm. com / logiciel / rationnel / café / blogs / ccpp-parallèle multi-cœurs / tags / c% 2B% 2B0x par exemple.

Si vous voulez être portable, jetez un oeil à boost :: thread-.

Autres conseils

Dans votre cas, il n'y a pas de condition de course. La variable est jamais remis à zéro retour à FAUX, est-il? Il est juste un interrupteur « s'il vous plaît mourir » pour le fil, non? Alors pas besoin de synchronisation d'aucune sorte.

La famille InterlockedXXX des fonctions utilise des commandes 3 opérandes atomiques d'Intel CPU (xadd et CMPXCNG). Ils sont donc beaucoup moins cher qu'une section critique. Et celui que vous voulez pour l'attribution de thread-safe est InterlockedCompareExchange ().

UPD. Et la marque de la variable volatile

Assurez-vous que m_bIsTerminated est marqué comme volatile, et vous devriez être ok. Bien qu'il me semble assez bizarre que tu // code plus après avoir réglé « est terminé » true. Que signifie exactement cette variable indique?

Votre « race condition » est que vos différents éléments de code // plus peuvent exécuter dans des ordres différents. Votre variable ne permet pas que. Votre but est de les amener à exécuter dans un ordre déterministe? Si oui, vous auriez besoin d'une variable condition d'attendre sur un fil et mettre dans un autre. Si vous ne voulez pas seulement les exécuter en même temps, une section critique serait bien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top