2011-09-08 5 views
3

Les données doivent être partagées entre les threads. Quelle est la meilleure méthode de synchronisation?Synchronisation des threads

Est-ce que le verrou est la meilleure approche ou Mutex?

namespace ConsoleApplication8 
{ 
    class Data 
    { 
     public int X 
     { 
      set; 
      get; 
     } 

     public int Y 
     { 
      get; 
      set; 
     } 

     public int result; 
    } 

    class Program 
    { 
     static int a; 
     private static object aLock = new object(); 

     static void Main(string[] args) 
     { 
      ParameterizedThreadStart aStart = new ParameterizedThreadStart(Addition); 
      Thread aThread = new Thread(aStart); 
      Data aData = new Data(); 
      aData.X = 10; 
      aData.Y = 20; 

      Thread aThread2 = new Thread(aStart); 
      aThread2.Start(); 


      aThread.Start(aData); 
      aThread.Join(); 
      aThread2.Join(); 
      Console.WriteLine("End of the program"); 
     } 

     static void Addition(object data) 
     { 
      var a = data as Data; 
      var b = a.X + a.Y; 
      a.result = b; 

      Console.WriteLine(a.result); 
      Thread.Sleep(1000); 
      Console.WriteLine("End of thread"); 
      updateValue(); 
     } 

     static void updateValue() 
     { 
      lock (aLock) 
      { 
       a++; 
      } 
     } 
    } 
} 
+4

Définir les critères "meilleurs". Est-ce que la pomme est meilleure que l'orange? – zerkms

+1

Ou voulez-vous juste connaître la différence de serrure et de mutex? – erikH

+0

regarder même ces postes: http://stackoverflow.com/questions/1164038/monitor-vs-mutex-in-c http://stackoverflow.com/questions/1763251/lock-monitor-mutex – Rev

Répondre

5

Vous avez deux endroits où vous êtes fils « de synchronisation ».

Vous utilisez Thread.Join pour attendre que vos threads soient terminés avant de poursuivre votre discussion principale. C'est très bien.

Vous utilisez également un verrou pour vous assurer qu'un seul thread à la fois incrémente votre variable de compteur a. C'est aussi bien, mais peut être amélioré. Il y a une classe appelée Interlocked dans System.Threading qui peut effectuer l'incrément pour vous d'une manière thread-safe.

Interlocked.Increment(ref a); 

Votre code n'utilise la variable a en deux endroits - à l'intérieur Addition vous avez une variable locale a que shadows la variable externe statique a. Je suppose que c'est juste une coïncidence.

Un autre problème est que votre méthode Addition prend un object en tant que paramètre. Je comprends pourquoi cela ne prend pas Data comme paramètre car ParameterizedThreadStart nécessite un objet. Il y a un meilleur moyen de contourner cela.

Essayez ce code à la place:

private static int __counter = 0; 

public class Data 
{ 
    public int X { set; get; } 
    public int Y { set; get; } 
    public int Result { set; get; } 
} 

private void Addition(Data data) 
{ 
    data.Result = data.X + data.Y; 
    Interlocked.Increment(ref __counter); 

    Thread.Sleep(1000); 

    Console.WriteLine(data.Result); 
    Console.WriteLine("End of thread"); 
} 

Maintenant Main peut être écrit comme:

void Main() 
{ 
    ParameterizedThreadStart pts = o => Addition(o as Data); 

    var t1 = new Thread(pts); 
    var t2 = new Thread(pts); 

    t1.Start(new Data { X = 10, Y = 20 }); 
    t2.Start(new Data { X = 13, Y = 42 }); 

    t1.Join(); 
    t2.Join(); 

    Console.WriteLine(__counter); 
    Console.WriteLine("End of the program"); 
} 

Cela devrait être un peu plus propre.

Je ne vois pas exactement quelles données vous partagez dans votre code. Peut-être pourriez-vous élaborer?

Questions connexes