Najprostszym sposobem na zrównoleglenie wykonywanych operacji jest klasa Thread. Poniższy przykład pokazuje, jak przy jej użyciu na wieloprocesorowej maszynie wykonywać operacje naprzemiennie.
public static void Run() { Thread t = new Thread(WriteY); t.Start(); for (int i = 0; i < 100; i++) { Thread.Sleep(i); Console.Write("x"); } } static void WriteY() { for (int i = 0; i < 100; i++) { Thread.Sleep(i); Console.Write("y"); } }
Warto pamiętać, że dla każdego wątku tworzony jest osobny memory stack. Informacje pomiędzy wątkami mogą być przekazywane np. poprzez zmienne statyczne. Nieumiejętne ich wykorzystanie może jednak spowodować poważne problemy. Aby uniknąć np. sytuacji, w której dwa wątki zapisują w tym samym czasie dane do jednej zmiennej, należy użyć tzw. Exclusive Lock. Użycie słowa kluczowego lock powoduje, że tylko jeden wątek w danej chwili może korzystać z zasobu, drugi musi poczekać.
public class LockTest { static bool done; static readonly object locker = new object(); public static void Run() { new Thread(Go).Start(); Go(); } static void Go() { lock (locker) { if (!done) { Console.WriteLine("Done"); done = true; } } } }
Blokowany wątek nie zużywa zasobów CPU.
Kolejną ważną operacją jest Join, służący do synchronizowania kolejności wykonywania operacji. Jeżeli z poziomu jednego wątku startujemy inny podrzędny, możemy zażądać aby dalsze wykonywanie kodu wstrzymać do zakończenia działania tego podrzędnego wątku.
public class JoinTest { public static void Run() { Thread t = new Thread(Go); t.Start(); for (int i = 0; i < 100; i++) Console.Write("x"); t.Join(); Console.WriteLine("Thread t has ended!"); } static void Go() { for (int i = 0; i < 1000; i++) Console.Write("y"); } }
Wątki można nazywać, co przydaje się podczas debugowania w Visual Studio. Można im także nadawać priorytety. Nadanie priorytetu decyduje o tym, ile czasu procesor poświęci na dany wątek. Domyślny priorytet to Medium.
public class ThreadNamePriorityTest { public static void Run() { Thread.CurrentThread.Name = "Main Thread"; Thread worker = new Thread(Go); worker.Name = "Worker"; worker.Priority = ThreadPriority.BelowNormal; worker.Start(); Go(); } static void Go() { Console.WriteLine("Hello from " + Thread.CurrentThread.Name); } }
Brak komentarzy:
Prześlij komentarz