3 votes

AttendreSingleObject ne fonctionne pas

Veuillez trouver le code ci-dessous :

#include 
int main(int argc, char* argv[])
{
    HANDLE _mutex = ::CreateMutex(NULL, FALSE, "abc");
    if (!_mutex)
        throw std::runtime_error("CreateMutex failed");

    if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
        throw std::runtime_error("WaitForSingleObject failed");

    printf("Must lock here\n");

    if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
        throw std::runtime_error("WaitForSingleObject failed");

    printf("Why come here????\n");
    return 0;
}

Je ne sais pas pourquoi la console affiche :

Must lock here
Why come here???

Est-ce que le mutex ne fonctionne pas? Je veux que le résultat ne montre que

Must lock here

Et bloquer après avoir affiché le texte ci-dessus.

4voto

naivnomore Points 730

Aucun autre fil autre que votre fil principal ne possède le mutex. C'est la raison pour laquelle il ne se bloque pas et vous voyez les deux instructions d'impression. Voici un extrait du lien MSDN qui explique clairement comment fonctionne le mutex.

Après qu'un fil obtient la propriété d'un mutex, il peut spécifier le même mutex dans des appels répétés aux fonctions d'attente sans bloquer son exécution. Cela empêche un fil de se bloquer en attendant un mutex qu'il possède déjà. Pour libérer sa propriété dans de telles circonstances, le fil doit appeler ReleaseMutex une fois pour chaque fois que le mutex a satisfait les conditions d'une fonction d'attente.

Vous pouvez créer plusieurs fils pour voir le comportement bloquant en action. Remarque : Votre code est également manquant l'appel à ReleaseMutex.

4voto

Logan Capaldo Points 22145

Si vous voulez un primitif de synchronisation qui se comporte comme vous l'avez décrit, vous pouvez utiliser un événement de réinitialisation automatique à la place.

 #include 
 #include 
 #include 
 int main(int argc, char* argv[])
 {
     HANDLE _mutex = ::CreateEvent(NULL, FALSE,         TRUE, NULL);
                                         // remise automatique  // initialement signalé
     if (!_mutex)
         throw std::runtime_error("CreateEvent failed");

     if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0) 
         throw std::runtime_error("WaitForSingleObject failed");
     // non signalé maintenant

     printf("Doit verrouiller ici\n");

     // bloquera indéfiniment jusqu'à ce que quelqu'un appelle SetEvent
     if (::WaitForSingleObject(_mutex, INFINITE) != WAIT_OBJECT_0)
         throw std::runtime_error("WaitForSingleObject failed");

     printf("Pourquoi venir ici ???? \n");
     return 0;
 }

0voto

x0n Points 26002

Mise à jour : renseignez-vous sur les mutex en c++

Je ne suis pas un expert en c++, mais un thread possède un mutex. Dans votre exemple, le même thread ouvre/crée le mutex nommé donc le deuxième appel ne sera pas bloqué.

Jetez un œil à ceci : "utiliser des objets mutex".

http://msdn.microsoft.com/fr-fr/library/ms686927(v=VS.85).aspx

-Oisin

0voto

Jive Dadson Points 3563

La "raison" pour laquelle cela ne "fonctionne" pas est qu'il n'y a aucune raison pour que cela fonctionne. Le paramètre FALSE indique que vous recherchez un mutex existant, entre autres choses. Lisez la documentation. http://msdn.microsoft.com/en-us/library/ms682411%28VS.85%29.aspx

Êtes-vous sûr de vouloir un mutex plutôt qu'une CRITICAL_SECTION?

Prograide.com

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.

Powered by:

X