Le fait que vous ne voyez aucun problème sur une machine uniprocesseur, mais que vous en voyez sur une machine multiprocesseur est un artefact de la granularité relativement grande du changement de contexte des threads sur une machine uniprocesseur. Un thread s'exécute pendant un temps N (millisecondes, nanosecondes, peu importe) avant que le planificateur de threads ne passe l'exécution à un autre thread. Un grand nombre d'instructions du CPU peuvent être exécutées dans la tranche de temps typique d'un thread. On peut considérer qu'il s'agit d'une assez grande portion de temps processeur exclusif "libre" pendant laquelle vous ne rencontrerez probablement pas de collisions de ressources parce que rien d'autre n'est exécuté sur le processeur.
En revanche, lorsqu'elles sont exécutées sur une machine multiprocessus, les instructions du processeur dans deux threads s'exécutent exactement en même temps. La taille de la portion de temps "libre" est proche de zéro.
Pour reproduire un problème de contention de ressources entre deux threads, il faut que le thread 1 accède à la ressource et que le thread 2 accède à la ressource en même temps ou presque.
Dans la commutation de threads à grande granularité qui a lieu sur une machine uniprocesseur, les chances qu'un changement de thread se produise exactement au bon endroit sont minces, de sorte que le programme peut ne jamais présenter de défaillance dans des conditions normales d'utilisation sur une machine uniprocesseur.
Dans une machine multiprocesseur, les instructions sont exécutées en même temps dans les deux threads, de sorte que les chances que le thread 1 et le thread 2 accèdent à la même ressource au même moment sont beaucoup, beaucoup plus grandes - des milliers de fois plus probables que dans le scénario uniprocesseur.
J'ai vu cela se produire de nombreuses fois : une application qui fonctionnait bien depuis des années sur des machines uniproques commence soudainement à échouer partout lorsqu'elle est exécutée sur une nouvelle machine multiproque. La cause est un bug latent de threading dans le code original qui n'a simplement jamais trouvé la bonne coïncidence de timeslicing pour se reproduire sur les machines uniproc.
Lorsque vous travaillez avec du code multithread, il est absolument impératif de tester le code sur du matériel multiproc. Si vous avez des problèmes de collision de threads dans votre code, ils se manifesteront rapidement sur une machine multiproc.
Comme d'autres l'ont noté, n'utilisez pas SuspendThread() à moins que vous ne soyez un débogueur. Utilisez les mutex ou d'autres objets de synchronisation pour assurer la coordination entre les threads.