2012-02-16 24 views
6

Używam std :: vector jako wspólne dane w aplikacji wielowątkowej. I hermetyzacji nitkę wewnątrz klasy, npstd :: wektor, wątek bezpieczeństwa, wielowątkowość

class ABC { 
public: 
    double a, b, c; 
}; 

boost::mutex mutex1; 

class XYZ { 
public: 
    XYZ(vector<ABC> & pVector) { 
     ptrVector = &pVector; 
     m_thread = boost::thread(&XYZ::Start, this); 
    } 
    ~XYZ() {} 
    void Start(); 
public: 
    vector<ABC> * ptrVector; 
    boost::thread m_thread; 
};  

void XYZ::Start() { 
    try { 
     while(1) { 
      boost::this_thread::interruption_point(); 
      for (unsigned int i=0; i<ptrVector->size(); i++) { 
       { 
        boost::mutex::scoped_lock lock(mutex1); 
        ptrVector->at(i).a = double(rand())/10000; 
        ptrVector->at(i).b = double(rand())/10000; 
        ptrVector->at(i).c = double(rand())/10000; 
       } 
      } 
     } 
    } 
    catch(boost::thread_interrupted) {} 
    catch(std::exception) {} 
} 

Kiedy zamknąć aplikację, czasami w debugowania, będą 2 komunikaty o błędach czasami nie będzie żadnych komunikatów o błędach. Często słyszałam, że ludzie mówiący o std :: vector nie są bezpieczni dla wątków, czy to jest jeden z przypadków? Używam Visual Studio 2008, zwiększ wątek, rozmiar wektora jest naprawiony. Czy ktoś może również zaoferować porady dotyczące sposobu użycia std :: vector w aplikacji wielowątkowej.

  1. Pierwsza szansa wyjątek w 0x7688b9bc w ETP.exe: Microsoft C++ wyjątek: std :: out_of_range w lokalizacji pamięci 0x02d8f7bc ..
  2. Pierwsza szansa wyjątek w 0x00e916e0 w ETP.exe: 0xc0000005: Dostęp lokalizacja odczytu naruszenia 0x00000008.
  3. Second Chance Assertion Failed: Plik C: \ program files (x86) \ Microsoft Visual Studio 9.0 \ VC \ include \ wektor, Linia drugie Chance Assertion Failed: Plik C: \ program files (x86) \ Microsoft wizualny studio 9.0 \ vc \ include \ vector98

Dzięki.

+0

wektor nie jest wątku bezpieczne, jeśli spróbujesz napisać do niego w tym samym czasie z różnych wątków to złamie. Blokujesz go i bez innych kodów, aby zobaczyć, jak go używasz, nie można powiedzieć, co może być nie tak. Ten konkretny kod sam w sobie wygląda dobrze. – Jarryd

+0

Oprócz bezpieczeństwa nici, prawdopodobnie musisz również wziąć pod uwagę sekwencję, w której twoje nici mają dostęp do wektora, Jeśli jeden wątek czyta z wektora, powinieneś upewnić się, że drugi wątek zapisał się do wektora przed lub co najmniej kod powinien obsługiwać warunek, dla którego wektor nie został zapisany. –

+0

@Jarryd jesteś rytuałem, w tym kodzie wydaje się, że blokuje wektor używając muteksa, jeśli to robi, to nie powinno to powodować problemu, ponieważ szczegóły musimy przejść przez kompletny kod –

Odpowiedz

22

W rzeczywistości jest to absolutnie bezcelowy do stanu X jest lub nie jest bezpieczny dla wątków! Musisz się zakwalifikować do jakiego rodzaju zastosowań. Na przykład prawie żadna klasa nie będzie "bezpieczna dla wątków", gdy zostanie użyta w jednym wątku, a zniszczona w innym.

Mimo to, oświadczenie, że std::vector<T> nie jest wątkowane, niezależnie od tego, jak często się to powtarza, jest błędne. Wydaje się jednak, że większość ludzi nie rozumie ani nie docenia gwarantowanych gwarancji bezpieczeństwa. std::vector<T> jest wątkowo bezpieczny w następującym znaczeniu:

  • Możesz odczytać obiekt wektorowy z wielu wątków jednocześnie.
  • Jeśli istnieje jeden wątek zmieniający obiekt wektorowy, nie będzie jednocześnie współbieżnych czytników ani pisarzy.
  • Dostęp do obiektu wektorowego nie koliduje z innymi obiektami wektorowymi.

Dotyczy samej struktury wektorowej. Dostęp do zamkniętego obiektu jest związany z wszelkimi regułami narzuconymi na nie. Nie są to oczywiście gwarancje bezpieczeństwa wątków, które wiele osób ma na myśli, ale wszystko, co silniejsze, nie działa z interfejsem kontenera.

+0

dziękuję za poradę. Teraz jest dla mnie o wiele bardziej zrozumiała. – 2607

+0

Przepraszamy, ale całkowicie się z Tobą nie zgadzamy, bezpieczna dla wątków jest znaną definicją, która stwierdza, że ​​implementacja powinna gwarantować współbieżność (wątek) chroniącą wspólne obszary w celu uniknięcia konfliktów, oznacza to, że klasa jest bezpieczna dla wątków, co oznacza, że zależy od użycia oznacza, że ​​nie jest bezpieczny dla wątków !, jak może być to właściwa odpowiedź? – Cross

+0

Możesz czytać z wielu wątków jednocześnie. Tak - tak długo, jak bariera pamięci zwolnienia miała miejsce po ostatniej modyfikacji i pojawiła się pasująca bariera pamięci na wszystkich wątkach czytających ... – Persixty

4

Zadzwoń pod ptrVector->size() bez uprzedniego zablokowania. To może być łatwo przyczyną twoich problemów. Pamiętaj, aby zablokować swój wektor przed odczytaniem lub zapisaniem.

+1

Powiedział, że rozmiar wektor jest ustalony, więc nie powinien powodować problemu. Jednakże, ponieważ nie mamy więcej kodu, nie wiemy, czy dodaje go do wątku w niebezpieczny sposób, nie wiedząc o tym. – Jarryd