2012-01-08 24 views
21

Zastanawiam się, czy jest to całkowicie bezpieczne dla wątków i czy zmienne słowo kluczowe powinno być na miejscu.Czy to (volatile bool) zawsze jest bezpieczne?

using System.Threading; 

class Program 
{ 
    private static volatile bool _restart = true; 

    private static void Main() 
    { 
     while (_restart) 
     { 
      // Do stuff here every time for as long as _restart is true 
      Thread.Sleep(1); 
     } 
    } 

    private static void SomeOtherThread() 
    { 
     Thread.Sleep(1000); 
     _restart = false; 
    } 
} 

Myślę, że tak, ale chcę dwukrotnie sprawdzić, ponieważ nie jestem w 100% pewny, że chcę tylko mieć pewność.

Myślę, że zmienne słowo kluczowe jest wymagane, ponieważ wtedy nigdy nie byłoby możliwe, aby wartość była przechowywana w rejestrach lub podobne optymalizacje.

+0

To nie jest tak naprawdę to, co oznacza wątek bezpieczny. Bezpieczny dla wątków (zazwyczaj) oznacza, że ​​wiele wywołań do tej samej klasy/biblioteki nie spowoduje zdmuchnięcia statycznych danych przechowywanych przez bibliotekę. –

+0

W twoim przykładzie jednak, jeśli wszystko, co chcesz zrobić, to oznaczenie innego wątku, nie widzę tego, co to nie zadziała. –

+0

@ Jonathon Reinhart Tak, mam tylko flagę. Jeśli to nie jest bezpieczeństwo wątków, czy jest to współbieżność? – Aidiakapi

Odpowiedz

11

Co odpowiedział SLaks jest poprawny, oczywiście, ale aby odpowiedzieć na Twoje pytanie: tak w obu przypadkach: jest to bezpieczne, to powinny być zadeklarowane zmienne.

+0

Dziękuję, właśnie to chciałem wiedzieć :) – Aidiakapi

10

Powinieneś wymienić całą konstrukcję na ManualResetEvent, która jest zarówno wątkowa, jak i szybsza.

private static readonly ManualResetEvent ev = new ManualResetEvent(); 

private static void Main() 
{ 
    ev.WaitOne() 
} 

private static void SomeOtherThread() 
{ 
    Thread.Sleep(1000); 
    ev.Set(); 
} 
+2

To jest * nie * to, czego chcę, nie chcę, aby główny wątek (w tym przypadku) spał. Po prostu chcę, żeby kontynuował iterację. W przeciwnym razie użyłbym innej konstrukcji. Przepraszam, że nie było to jasne, zobacz aktualizację. – Aidiakapi

+0

+1, co jest lepsze .., jednak @Aidiakapi zauważy, że twoje rozwiązanie będzie działać poprawnie; słowo kluczowe 'volatile' opróżni nową wartość' _restart = false' do pamięci głównej, dzięki czemu zaktualizowana wartość będzie widoczna w metodzie 'Main' .. –

Powiązane problemy