2010-09-25 30 views
2

OK. Je veux avoir deux threads en cours d'exécution. Code actuel:C# Multithreading

public void foo() 
    {  
      lock(this) 
      { 
       while (stopThreads == false) 
       { 
        foreach (var acc in myList) 
        { 
        // process some stuff 
        } 
       } 
      } 
    } 

    public void bar() 
    {  
      lock(this) 
      { 
       while (stopThreads == false) 
       { 
        foreach (var acc in myList) 
        { 
        // process some stuff 
        } 
       } 
      } 
    } 

Les deux accèdent à la même liste, le problème est que le premier thread « foo » ne libère pas le verrou je suppose; car "bar" ne commence que lorsque "foo" est terminé. Merci

+0

Oui, la barre ne commencera qu'après que foo soit terminée, c'est comme ça que le verrou fonctionne, vous devriez donner plus de détails sur la manière dont vous voulez que votre code fonctionne. –

+0

lire une définition de sémaphore/mutex, puis supprimer le verrou –

Répondre

3

Oui, c'est ainsi que le verrouillage est conçu pour fonctionner.

Le mot-clé de verrouillage marque un bloc de déclaration comme une section critique en obtenant le verrou -exclusion mutuelle pour un objet donné, exécution d'une instruction, puis en relâchant le verrou.

L'exclusion mutuelle signifie qu'il peut y avoir au plus un thread qui détient le verrou à tout moment.

Verrouiller est une mauvaise idée et est déconseillé. Vous devriez créer un objet privé et le verrouiller à la place. Pour résoudre votre problème, vous pouvez verrouiller deux objets différents.

private object lockObject1 = new object(); 
private object lockObject2 = new object(); 

public void foo() 
{  
    lock (lockObject1) 
    { 
     // ... 
    } 
} 

public void bar() 
{  
    lock (lockObject2) 
    { 
     // ... 
    } 
} 

Sinon, vous pouvez réutiliser le même verrou, mais le déplacer à l'intérieur de la boucle de telle sorte que chaque boucle a une chance de procéder:

while (stopThreads == false) 
{ 
    foreach (var acc in myList) 
    { 
     lock (lockObject) 
     { 
      // process some stuff 
     } 
    } 
} 

Cependant, je vous suggère de passer un peu de temps pour comprendre ce qui est aller plutôt que de réordonner les lignes de code jusqu'à ce qu'il semble fonctionner sur votre machine. Écrire du code multithread correct est difficile.

Pour arrêter un fil Je recommande cet article:

+0

Qu'en est-il de la variable stopThreads, il n'est pas sûr de thread, peut-être il a obtenu le résultat totalement faux. – TalentTuner

+0

@saurabh: Cela pourrait devenir volatil. Ou il pourrait être transformé en une propriété sûre de thread. –

+0

merci, cela a fonctionné. – foobar

0

Le problème que vous avez est que vous travaillez avec une serrure très grossière. A la fois Foo et Bad ne fonctionnent pas en même temps, car celui qui commence en premier arrête l'autre pour le CYCLE DE TRAVAIL COMPLET.

Il devrait, cependant, verrouiller SEULEMENT PENDANT QU'IL PREND DES CHOSES DE LA LISTE. Foreach ne fonctionne pas ici - par définition. Vous avez à mettre en place une deuxième liste et avoir chaque thread supprimer le TOP ITEM (tout en lockin), puis travailler dessus.

En gros:

  • Foreach ne fonctionne pas, comme les deux fils courront la liste compelte
  • En second lieu, les verrous doivent être granuleuse en ce sens qu'ils se bloquent uniquement lorsque nécessaire.

Dans votre cas, vous verrouillez dans foo ne sera libéré que lorsque foo est terminé.

1

Puisque vous ne posez pas vraiment de question, je vous suggère de lire un tutoriel sur le fonctionnement du filetage. Un guide spécifique .Net peut être found here. Il présente les rubriques "Mise en route", "Synchronisation de base", "Utilisation de threads", "Threading avancé" et "Programmation parallèle".

De plus, vous vous verrouillez sur "this".Le Msdn dit:

En général, évitez de bloquer sur un type public ou au-delà des instances contrôle de votre code. Les constructions communes lock (this), lock (typeof (MyType)) et lock ("myLock") violent cette directive :

  • lock (this) est un problème si l'instance est accessible au public.

  • lock (typeof (MyType)) est un problème si MyType est accessible au public.

  • lock(“myLock”) est un problème parce que tout autre code dans le processus en utilisant la même chaîne, partagera le même verrou .

La meilleure pratique consiste à définir un objet privé à verrouiller, ou une variable d'objet statique privé pour protéger les données communes à toutes les instances.