2012-03-14 11 views
11

Jeśli mam obiekt C++ utworzony w wątku głównym, a następnie uruchamiam kolejny wątek, a następnie z tego wątku wywołuję publiczną funkcję członka obiektu, który utworzyłem, co się dzieje?Co się stanie, jeśli wywołam funkcję elementu obiektu z innego wątku?

Czy jest inaczej, jeśli funkcja publiczna ma parametry lub manipuluje elementami prywatnymi?

Czy zachowuje się inaczej w systemie Windows, Linux lub Mac OS?

Co się stanie, jeśli obiekt zostanie utworzony na stosie?

Odpowiedz

9

Istnieją dwa punkty, które liczą:

  • pierwsze, jak zwykle, trzeba esnure że żywotność instancji przekracza okres jego użytkowania.
  • Po drugie, dostęp do zmiennych w wielu wątkach musi być zsynchronizowany, aby zapobiec wyścigowi.

To wszystko ludzie.

+0

Jeśli obiekt został utworzony na stercie, czy istnieje prosty sposób usunięcia obiektu po zakończeniu ostatniego wątku? – neckTwi

3

Jeśli mam obiekt C++ utworzony w głównym wątku, a następnie rozpocząć kolejny wątek, i od tego wątku nazywam publiczną funkcję członkowską obiektu utworzonego, co się dzieje?

To zależy od czasu życia obiektu.

Jeśli obiekt zostanie utworzony na stercie (pamięć dynamiczna przy użyciu new), wówczas drugi wątek będzie prawidłowo uzyskiwał dostęp do elementów obiektu (zakładając, że nie ma warunków wyścigu), chyba że czas życia obiektu zakończył się wywołaniem delete w pierwszym wątku.

Jeśli obiekt zostanie utworzony na stosie (lokalnie) w pierwszym wątku, będzie można uzyskać niezdefiniowane zachowanie * *, jeśli okres istnienia utworzonego obiektu zakończył się przed uzyskaniem dostępu do drugiego wątku.

Dlaczego można uzyskać dostęp do obiektu na stosie w drugim wątku?

Każdy wątek ma swój własny stos i ile obiekt utworzony na stosie wątku jest ważne i żywe Użytkownik będzie próbował uzyskać dostęp do lokalizacji adresu, który nie wskazuje na jakiekolwiek ważnego obiektu w drugim wątku.
Należy zauważyć, że każdy proces ma przestrzeń adresową, a wszystkie wątki w tym samym procesie współużytkują tę samą przestrzeń adresową, w związku z czym adres zmiennej można uzyskać w drugim wątku. Musisz jednak upewnić się, że adres zawiera prawidłowy obiekt.

Czy jest inaczej, jeśli funkcja publiczna ma parametry lub manipuluje elementami prywatnymi?

Specyfikatory dostępu i wielowątkowość nie są w ogóle powiązane.
We wszystkich wątkach obowiązują te same reguły specyfikacji dostępu.

Czy zachowuje się inaczej w systemie Windows, Linux lub Mac OS?

Odpowiedź na #1 jest gwarantowana we wszystkich systemach operacyjnych.

+5

Niestety, to nie jest prawda. Jeśli czas życia obiektu jest większy niż czas życia wątku, to jest w porządku. Ale uważaj na warunki wyścigowe. – knivil

+0

@knivil: True. Zdałem sobie sprawę, że tęskniłem mówiąc to. –

4
  1. Każdy wątek ma własny stos, dzięki czemu możesz mieć równoczesne strumienie wykonania. Twoim obowiązkiem jest, aby obiekt był bezpieczny dla wątków.

  2. To nie ma znaczenia. Prywatni członkowie są jednak kandydatami do wyścigów.

  3. Jeśli utworzysz obiekt na stosie, nie będzie on dostępny z innego wątku.

+8

"Jeśli utworzysz obiekt na stosie, nie będzie on dostępny z innego wątku." Chyba że przekażesz odniesienie do tego obiektu do drugiego wątku. –

+0

@NicolBolas: Tak, masz rację, oczywiście. Powinienem lepiej powiedzieć "widoczny". – Matthias

2

W porównaniu do oryginalnego zachowania nie powinno być żadnych różnic, jeśli zostały utworzone na stercie. Są jednak oczywiście winowajcy, zwykle określani terminem "bezpieczeństwo nici". Jeśli uzyskasz dostęp do tego samego członka z różnych wątków, musisz upewnić się, że dostęp do tych samych zasobów nie prowadzi do "stanu wyścigu".

Aby uniknąć wyścigu, można użyć różnego rodzaju "zamków", na przykład muteksów itp. Podczas korzystania z obiektów blokujących istnieje inny sprawca: Niebezpieczeństwo "zakleszczenia", jeśli dwaj dodatkowi czekają na siebie nawzajem i oryginał blokada nigdy nie zostanie zwolniona.

2

Będzie działać doskonale. Obiekty nie należą do żadnego konkretnego wątku i równie dobrze można je wywoływać z dowolnego miejsca.

Jednak jest to ważne, wywołanie funkcji członka na dwóch wątkach w tym samym czasie spowoduje problemy w przypadku aktualizacji niektórych danych w jednym wątku podczas czytania w innym. Musisz albo ułożyć kod, aby się to nie stało, albo upewnić się, że twój wątek koordynuje dostęp (najprawdopodobniej przy użyciu mutex).

2

To, co się dzieje, to dokładnie to, co się stanie, jeśli zadzwonisz z tego samego wątku. Ten sam kod maszyny zostanie wykonany. Jedyną różnicą potencjałów jest to, że możesz mieć kilka wątków uzyskujących dostęp do obiektu pod adresem w tym samym czasie; Twoim zadaniem jest chronić się przed tym (przynajmniej jeśli dowolny wątek modyfikuje obiekt —, w przeciwnym razie nie jest wymagane żadne zabezpieczenie).

W przypadku obiektu na stosie należy wziąć pod uwagę czas życia , ale tak jest i tak; zapisz wskaźnik do obiektu na stosie w zmiennej globalnej, a następnie pozostaw zakres, w którym obiekt został zdefiniowany, a zmienna globalna stanie się wskaźnikiem zwisającym; próba uzyskania dostępu do obiektu poprzez to jest niezdefiniowanym zachowaniem (i wywołaniem na nim niestanowej funkcji składowej uważa się, że należy z niego korzystać). Niezależnie od tego, czy dostęp jest z tego samego wątku czy z innego wątku, nic się nie zmienia.

Powiązane problemy