2009-08-05 11 views
19

Słyszałem, że miksowanie rozwidlania i gwintowania w programie może być bardzo problematyczne, często skutkujące tajemniczym zachowaniem, szczególnie gdy mamy do czynienia z zasobami współdzielonymi, takimi jak zamki, rury, deskryptory plików. Ale nigdy w pełni nie rozumiem, jakie dokładnie niebezpieczeństwa są i kiedy mogą się one zdarzyć. Byłoby wspaniale, gdyby ktoś z doświadczeniem w tej dziedzinie mógł wyjaśnić nieco więcej szczegółów na temat pułapek i tego, co należy zachować podczas programowania w takim środowisku.widelec w wielowątkowym programie

Na przykład, jeśli chcę napisać serwer, który zbiera dane z różnych zasobów, jednym z rozwiązań, które myślałem, jest to, aby serwer spawnował zestaw wątków, każdy popen wywoływał inny program do wykonania pracować, otwierać rury, aby odzyskać dane od dziecka. Każda z tych odpowiedzi wątków dla własnej pracy, brak wymiany danych w b/w nich, a gdy dane są zbierane, główny wątek ma kolejkę, a te wątki robocze po prostu umieszczą wynik w kolejce. Co może pójść nie tak z tym rozwiązaniem?

Proszę nie zawężać odpowiedzi, po prostu "odpowiadając" na mój przykładowy scenariusz. Wszelkie sugestie, alternatywne rozwiązania lub doświadczenia, które nie są związane z tym przykładem, ale pomocne w zapewnieniu czystego projektu, byłyby świetne! Dzięki!

+0

Tutaj jest [dobra wiadomość] (http://thorstenball.com/blog/2014/10/13/why-threads-cant-fork/) z dodatkowymi informacjami na temat tego tematu - –

Odpowiedz

0

To naprawdę bardzo proste. Problemy z wieloma wątkami i procesami zawsze wynikają z udostępnionych danych. Jeśli nie ma udostępnionych danych, nie mogą wystąpić żadne możliwe problemy.

W twoim przykładzie udostępnione dane to kolejka należąca do głównego wątku - pojawią się tutaj potencjalne rywalizacje lub warunki wyścigu. Typowe metody "rozwiązywania" tych problemów obejmują schematy blokowania - wątek roboczy zablokuje kolejkę przed wstawieniem jakichkolwiek danych, a główny wątek zablokuje kolejkę przed jej usunięciem.

+0

Czy metadane malloc są liczone jako "udostępnione dane"? :) – bdonlan

+0

Nie wiem - normalnie, twoje normalne biblioteki są napisane w taki sposób, aby były bezpieczne dla wątków (czasami musisz wybrać ich bezpieczne wersje). To zależy od tego, jaka jest twoja definicja udostępnianych danych i jaki jest wpływ. –

+0

często nie możemy uniknąć udostępniania danych. takie jak rury, deskryptory plików itp. Są zawsze udostępniane w trybie fork. Teraz pod linuxem można ustawić flagę O_CLOEXEC, aby można było zamknąć fd przy rozwidleniu (myślę, co to znaczy zamknąć fd w przestrzeni adresowej dziecka), chociaż nie wiem, czy to pomogłoby, gdybyśmy dodali wątki w ? na przykład co się stanie, jeśli otworzę rury w jednym wątku i widelec? co jeśli inny wątek również rozwidla? które dziecko będzie mogło zobaczyć fajkę? – jimx

16

Problem z rozwidlaniem, gdy masz uruchomione wątki, polega na tym, że widelec kopiuje tylko stan procesora jednego wątku, który go wywołał. To tak, jakby wszystkie inne wątki po prostu umarły, natychmiast, gdziekolwiek się znajdują.

Wynikiem tego są blokady, które nie są zwalniane, a udostępnione dane (takie jak kupon malloc) mogą być uszkodzone.

pthread nie oferuje pthread_atfork funkcję - w teorii, można wykorzystać każdą blokadę w programie przed rozwidlone, zwolnij je później i może uczynić go przy życiu - ale jest to ryzykowne, bo zawsze można przegapić jeden. I, oczywiście, stosy innych wątków nie zostaną uwolnione.

+0

Czy możesz trochę wyjaśnić, co to znaczy, że "zamki nie są uwalniane"? Z perspektywy dziecka, prawda? Więc dziecko nigdy nie może zdobyć blokady? – jimx

+0

Prawidłowo. Widelec klonuje wszystkie zamki, gdy są jeszcze zablokowane. – bdonlan

Powiązane problemy