2 votes

L'utilisation de l'API Windows pour créer 100 threads avec une méthode de verrouillage mutex induit un résultat inattendu, comment le corriger ?

Je suis en train d'essayer l'API de <Windows.h> avec un simple programme multithread qui imprime l'index donné de chaque thread de manière synchronisée, avec un délai d'une seconde entre chaque impression.

Ce programme est écrit en C, mais je suppose que ce sera la même chose en C++.

Et voici le code :

#include <stdio.h>
#include <stdlib.h>

#include <windows.h>

#define THREAD_LEN 100
HANDLE mutex_handle = NULL;
HANDLE thread_handle[THREAD_LEN];

DWORD WINAPI execute(LPVOID param) {
  int id = *(int *) param;
  if (WAIT_OBJECT_0 != WaitForSingleObject(mutex_handle, INFINITE)) {
    printf("ERROR_CODE: %d\n", GetLastError());
  }
  printf("[%d]\n", id);
  Sleep(1000);
  ReleaseMutex(mutex_handle);
  return 0;
}

int main(void) {
  mutex_handle = CreateMutex(NULL, FALSE, NULL);
  DWORD thread_id;
  for (int i = 0; i < THREAD_LEN; i++) {
    int *id = (int *) malloc(sizeof(int));
    *id = i;
    thread_handle[i] = CreateThread(NULL, 
                                    0, 
                                    (LPTHREAD_START_ROUTINE) execute, 
                                    id,
                                    0, 
                                    &thread_id);
    if (!thread_handle[i]) {
      return 1;
    }
  }
  WaitForMultipleObjects(THREAD_LEN, thread_handle, TRUE, INFINITE);
  for (int i = 0; i < THREAD_LEN; i++) {
    CloseHandle(thread_handle[i]);
  }
  CloseHandle(mutex_handle);
  return 0;
}

Mais il présente un comportement inattendu : Lorsque je l'exécute via cmd, la méthode Sleep(1000) ne fonctionne pas (le programme n'imprime pas un identifiant par seconde, mais en une seule fois), et tous les threads n'ont pas leur identifiant imprimé.

[0]
ERROR_CODE: 6
ERROR_CODE: 6
[30]
ERROR_CODE: 6
[5]
[29]
ERROR_CODE: 6
[33]
ERROR_CODE: 6
[34]
ERROR_CODE: 6
[41]
ERROR_CODE: 6
[37]
ERROR_CODE: 6
ERROR_CODE: 6
[47]
ERROR_CODE: 6
ERROR_CODE: 6
[55]
ERROR_CODE: 6
[43]
ERROR_CODE: 6
[44]
ERROR_CODE: 6
[38]
ERROR_CODE: 6
ERROR_CODE: 6
[17]
ERROR_CODE: 6
[50]
ERROR_CODE: 6
[76]
ERROR_CODE: 6
[11]
[36]
ERROR_CODE: 6
[42]
ERROR_CODE: 6
[57]
ERROR_CODE: 6
[13]
ERROR_CODE: 6
[58]
ERROR_CODE: 6

Cependant, lorsque je réduis le nombre de fils à 60, le programme fonctionne comme prévu.

[0]
[3]
[2]
[1]
[6]
[34]
[37]
[39]
[8]
[9]
[46]
[11]
[51]
[53]
[55]
[58]
[16]
[17]
[18]
[19]
[20]
[22]
[21]
[23]
[24]
[25]
[26]
[27]
[28]
[29]
[30]
[31]
[32]
[33]
[4]
[36]
[35]
[38]
[5]
[7]
[40]
[42]
[41]
[43]
[44]
[45]
[10]
[47]
[48]
[49]
[50]
[12]
[52]
[13]
[54]
[14]
[56]
[57]
[59]
[15]

2voto

Joshua Points 13231

Vous ne pouvez pas attendre plus de 64 objets avec WaitForMultipleObjects. Décomposez votre attente, en créant plusieurs threads pour attendre 64 objets à la fois si nécessaire.

En essayant ceci, WaitForMultipleObjects retourne immédiatement, donc vous fermez votre mutex immédiatement, et WaitForSingleObject se plaint que le mutex est déjà fermé.

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