Il y a deux façons principales. L'un, peut-être le plus simple, consiste simplement à envoyer à chaque thread sa propre copie de la structure de données. De cette façon, vous n'aurez pas à utiliser la synchronisation pour protéger les données, car aucun thread ne partage les données d'un autre thread.
Mais cela ne fonctionnera pas dans beaucoup de situations. Parfois, vous avez vraiment besoin de partager une structure de données commune. Dans ce cas, vous devez protéger la structure de données avec une certaine forme d'objet de synchronisation. Boost.Threads fournit des plateformes multiplateformes, et je suis sûr que quelqu'un vous montrera comment les utiliser. Puisque vous avez demandé spécifiquement à propos de Windows, je vais vous montrer une méthode Windows.
Vous pouvez utiliser un CRITICAL_SECTION. Tout d'abord, vous devez initialiser la section critique dans votre fil conducteur, avant le coup d'envoi de vos threads de travail:
int main()
{
// ...
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);
// ...
}
passe ensuite le pointeur sur le cs à chaque thread de travail. (Ceci est laissé comme un exercice.) Dans chaque thread de travail, entrez le cs avant de travailler avec vos données, et laissez-le lorsque vous avez terminé.
CRITICAL_SECTION* pcs = ...; // passed in from main thread
EnterCriticalSection(pcs); // this will block until the cs is "available"
list->next = ...
LeaveCriticalSection(pcs); // makes the cs available to other threads
Ce qui précède est psudocode, et a beaucoup de place pour l'amélioration. Par exemple, la section critique doit être enveloppée dans un objet RAII afin qu'il soit automatiquement détruit lorsque vous avez terminé. De même, le verrouillage et le déverrouillage doivent également être effectués dans un objet RAII afin qu'il soit toujours déverrouillé, peu importe comment vous quittez votre fonction de thread, même face à des exceptions.
Notez qu'une CRITICAL_SECTION ne peut être utilisée que par un seul processus. Si vous devez utiliser un objet de type mutex sur plusieurs processus (pas ce dont vous avez besoin ici), alors vous devez utiliser un named mutex à la place.
La première chose à faire est d'encapsuler la liste entière et tout ce qui l'accède directement dans une classe et forcer tout ce qui en veut l'accès à utiliser la classe. Cela empêchera le code dupliqué et garantira que tout ce qui utilise la liste respecte la méthode de synchronisation que vous aurez choisie. – Blrfl