Brzmi jak państwo jakichkolwiek blokad w procesie są kopiowane do procesu potomnego gdy prąd widelce wątek (który wydaje się błędem projektu i pewna do impasu).
Nie jest to błąd projektowy, a raczej fork()
poprzedzający wielowątkowość jednoprocesową. Stan wszystkich zamków jest kopiowany do procesu potomnego, ponieważ są po prostu obiektami w pamięci; cała przestrzeń adresowa procesu jest kopiowana tak jak w fork. Są tylko złe alternatywy: albo skopiuj wszystkie wątki na widełki, albo odmów rozwidlenie w aplikacji wielowątkowej.
W związku z tym, fork()
w wielowątkowość programu nigdy nie było bezpieczne, o ile nie następuje po execve()
lub w procesie potomnym.
Czy zastępuje gwintowanie.Zablokuj wieloprocesorowo. Blokuj wszędzie, unikaj tego problemu i pozwól nam bezpiecznie łączyć wątki i widelce?
nr Nic nie sprawia, że jest bezpieczny łączyć wątki i widelce, nie można zrobić.
Problem polega na tym, że gdy masz wiele wątków w procesie, po wywołaniu systemowym fork()
nie można bezpiecznie kontynuować uruchamiania programu w systemach POSIX.
Na przykład, Linux podręczniki fork(2)
:
- Po
fork(2)
w wielowątkowym programem, dziecko może bezpiecznie wywołać tylko asynchroniczny sygnał bezpieczne funkcje (patrz signal(7)
) aż do czasu, kiedy to nazywa się execve(2)
.
tj. jest w porządku do fork()
w programie wielowątkowym, a następnie wywoływać tylko funkcje asynchroniczne z sygnałami (co jest raczej ograniczonym podzbiorem funkcji C), dopóki proces potomny nie zostanie zastąpiony innym plikiem wykonywalnym!
funkcja
niebezpieczne C wymaga w procesie dzieci są wówczas przykładowo
malloc
alokacji pamięci dynamicznej
- żadnych
<stdio.h>
funkcje wejściowych sformatowanych
- większość
pthread_*
funkcje wymagane do obsługi stanu wątku, w tym tworzenie nowych wątków ...
Tak więc jest bardzo mało tego, co dziecko proces może faktycznie bezpiecznie zrobić. Niestety twórcy rdzeni CPython bagatelizują problemy spowodowane przez to. Nawet teraz documentation mówi:
Zauważ, że bezpiecznie rozwidlone wielowątkowe proces jest problematyczne.
Całkiem eufemizm za "niemożliwe".
Jest bezpieczny w użyciu wieloprocesorowe z proces Pythona, który ma wiele wątków kontroli pod warunkiem, że jesteś nie stosując metodę fork
startu; w Pythonie 3.4+ jest to now possible to change the start method. W poprzednich wersjach Pythona, w tym w całym Pythonie 2, systemy POSIX zawsze zachowywały się tak, jakby jako metoda początkowa była określona fork
; spowodowałoby to niezdefiniowane zachowanie.
Problemy nie są ograniczone tylko do obiektów threading.Lock
ale wszystkich blokadę utrzymywaną przez biblioteki standardowej C, C itd. Rozszerzenia Co gorsza, że większość czasu ludzie powiedzieliby „działa na mi”. ... dopóki nie przestanie działać.
Były nawet przypadki, w których pozornie jednostronny program w języku Python jest wielowątkowy w systemie MacOS X, powodując awarie i zakleszczenia podczas korzystania z wieloprocesowości.
Innym problemem jest to, że wszystkie otwarte uchwyty plików, ich użycie, współdzielone gniazda mogą zachowywać się dziwnie w programach z rozwidleniami, ale tak by było nawet w programach jednowątkowych.
TL; DR: using multiprocessing
w programach wielowątkowych, z rozszerzeniami C, z otwartych gniazd itp:
- porządku w 3.4+ & POSIX jeśli jawnie określić metodę wyjścia, które nie jest
fork
,
- dobrze w Windowsie, ponieważ nie obsługuje rozwidlania;
- w Pythonie 2 - 3.3 na POSIX: w większości będziesz strzelał sobie w stopę.
W tym wydaniu "sposobu kontrolowania podtytułu, jeśli dołączam inny wątek", moja opinia brzmi: ** nie ma mowy **. powinniśmy preferować wieloprocesowość. Blokować wszędzie? NIE, jeśli proces odbywa się w nieskończonej pętli! – dsgdfg