2017-09-25 6 views
0

Le code suivant imprime normalement BA mais parfois il peut imprimer BBAA, BAAB, ... Comment est-il possible d'obtenir deux A ou B avec? Cependant, ce code n'imprime jamais trois A ou B. Les deux fonctions (produire et consommer) exécutent beaucoup de threads. Merci d'avance.Comportements de threads impairs

int permission; 
void set_permission(int v) { 
    permission = v; 
    printf("%c", v + 'A');fflush(stdin); 
} 
void* produce(void*) { 
    for (;;) { 
     pthread_mutex_lock(&mr1); 
     set_permission(1); 
     while (permission == 1); 
     pthread_mutex_unlock(&mr1); 
    } 
} 
void* consume(void*) { 
    for (;;) { 
     pthread_mutex_lock(&mr2); 
     while (permission == 0); 
     set_permission(0); 
     pthread_mutex_unlock(&mr2); 
    } 
} 
+5

'fflush (stdin);' provoque un comportement défini; ne le fais pas –

+1

Je vois 2 mutex non apparentés. On dirait que vous pouvez supprimer vos procédures de synchronisation et obtenir le même résultat. –

+0

Quelles sont les références à deux mutex différents? Si le code essaie de protéger la variable 'permission' alors toutes les références mutex doivent être au même mutex. Suggérer: 'for (;;) {while (! Permission); pthread_mutex_lock (&mr1); set_permission (1); pthread_mutex_unlock (&mr1);} 'le thread consommateur serait très similaire AND utiliserait le même mutex – user3629249

Répondre

4

Vos threads ne sont pas synchronisés, car ils n'utilisent pas le même mutex.

L'autre thread peut par chance seulement gérer permission à 1 ou 0, mais ne parvient pas encore à produire de sortie. Dans ce cas, il semble que le premier thread a couru deux tours complets.

L'écriture par le thread correspondant peut également obtenir entièrement perdu, lorsque le contenu de la mémoire est synchronisé entre les coeurs et les deux threads écrits. Le mutex empêche également cela, car il établit un ordre strict d'accès à la mémoire, qui, pour simplifier, garantit que tout ce qui s'est passé sous la protection d'un mutex est entièrement visible pour l'utilisateur suivant du même mutex.

L'impression du même caractère 3 fois ou plus serait très peu probable, car il y a au plus une écriture entre les deux, donc au plus une écriture perdue, ou une sortie hors de l'ordre. Ce n'est pas garanti cependant.

Si vous travaillez sur un système sans aucune synchronisation implicite de la mémoire, votre code pourrait également se retrouver dans une impasse, car les écritures effectuées sous un mutex ne se propagent jamais aux utilisateurs de l'autre. (Cela ne se produit pas car il y a encore une certaine synchronisation introduite par les opérations d'E/S.)

+0

J'ai placé printf avant l'affectation et cela a éliminé tous les caractères doubles! Merci un million! – vollitwr

+1

@vollitwr Tant que vous n'utilisez pas le même mutex, cela n'a éliminé que la sortie hors service. Votre code est toujours vulnérable aux écritures perdues, à moins que 'permission' soit [atomic] (http://de.cppreference.com/w/cpp/atomic/atomic) ou que vous utilisiez le même mutex. Cette erreur est beaucoup plus difficile à provoquer, mais cela peut toujours arriver. – Ext3h