Article View: pl.comp.lang.c
Article #267796Re: Ciemna strona C++
From: Sektor van Skijlen
Date: Mon, 03 Dec 2007 21:50
Date: Mon, 03 Dec 2007 21:50
156 lines
9278 bytes
9278 bytes
Dnia Mon, 26 Nov 2007 12:26:30 +0100, Marcin ?Qrczak? Kowalczyk skrobie: > Dnia 26-11-2007, Pn o godzinie 09:17 +0000, Sektor van Skijlen pisze: > > No dobrze - ale co taki sygnał może przerwać? > Stan blokowania sygnałów przez dany wątek ma postać pary (all, async), > gdzie all jest liczbą naturalną oznaczającą liczbę powodów, dla których > sygnały powinny być zablokowane, a async ma zakres 0..1. Ta przestrzeń > stanów daje to tylko trzy możliwe reakcje na sygnały: > (0, 0) - sygnał może być obsłużony w każdym momencie > (0, 1) - sygnał może być obsłużony tylko przez wybrane operacje, > które na coś czekają (tzw. tryb synchroniczny) > inne - sygnał jest kolejkowany do obsłużenia później > Stan blokowania jest jawnie zmieniany przez pewne funkcje, a także mniej > jawnie: > - Sygnały są blokowane na czas wzięcia muteksu, wzięcia read-write locka > (jak on się po polsku nazywa?), Blokada czytelnicy-pisarze. Przynajmniej takie spotkałem w książce pt. "Jądro systemu UNIX". > obliczania wartości leniwej zmiennej, > inicjalizacja modułu innego niż moduł główny, jawnego uruchomienia > finalizatora obiektu, obsługi wyjątku (chyba że zaznaczono inaczej), > obsługi sygnału. Obsługi sygnału również? A co w przypadku, gdy handler sygnału "spowoduje" sygnał? > - Konstrukcja zarządzająca zasobem wymagającym jawnego zwalniania > (Using) składa się z trzech części: pobranie zasobu, treść główna > i zwolnienie zasobu. Na czas pobierania zasobu asynchroniczne > sygnały są blokowane, a na czas zwalniania - wszystkie są blokowane. No to jest ok. > - Nowy wątek normalnie ma odblokowane sygnały, ale można utworzyć wątek > z zablokowanymi na starcie (co jest konieczne, jeśli chcemy uniknąć > okienka, kiedy wątek nie zdążył jeszcze określić innej funkcji obsługi > sygnałów). > (Leniwa zmienna to jest coś takiego, co przy pierwszej próbie odczytania > wartości wykonuje dane obliczenie, a przy następnej próbie zwraca to co > obliczono poprzednio. Pytanie o wartość leniwej zmiennej, która właśnie > się liczy przez inny wątek, czeka na zakończenie tego obliczenia. > Pytanie o wartość leniwej zmiennej, która właśnie się liczy przez ten > sam wątek, jest błędem. Znaczy się bottomem (w tym przypadku z powodu nieskończonej rekurencji). > Inicjalizacja modułu ma analogiczną semantykę > i wewnętrznie używa jednej leniwej zmiennej na moduł.) ok. > Operacje, które obsługują sygnały w trybie synchronicznym, to > czekanie na condition, na zakończenie wątku, na zakończenie procesu, > na wejście-wyjście (w tym na otwarcie pliku, który może być rurką - > wtedy open jest blokujące), na upływ danego czasu. Ale nie na mutex, > na leniwą zmienną ani na finalizator obiektu. > Nie będę teraz wnikać w bardziej szczegółowe przypadki: leniwe listy > (które są podobne do leniwych zmiennych, ale mają dodatkowe komplikacje > związane z sygnałami), eksperymentalne kolejki multipleksujące zdarzenia, > czekanie na muteks przy wyjściu z lokalnego zwolnienia, a nie przy > wejściu na lokalne zajęcie, fork wielowątkowego procesu i inne. No super - tylko czy teraz możesz używając właściwości języka określić dany zakres instrukcji "ręcznie" jako nieblokowalny w określonym trybie? Wraz, oczywiście, z ewentualnymi możliwymi do zdefiniowania zastrzeżeniami, że danego bloku z pewnych przyczyn nie można "zalakowć" (bo np. w środku wywołuje instrukcję, która w razie niepowodzenia rzuca wyjatkiem, co oznacza, że instrukcja dla niej nadrzędna nie może zostać wykonana)? > > Oczywiście wątek nadrzędny powinien dostać killa w przypadku wykrycia > > zakleszczenia. > Jakiego zakleszczenia i jaki wątek nadrzędny? W Kogucie wątki nie mają > relacji nadrzędny-podrzędny. No, wątek nadrzędny, to ten wątek, który odpala inne wątki. Przynajmniej tak się to przyjmuje w modelu obiektowym wątków, w zasadzie w tej chwili jedynym słusznym (posix pod to oczywiście również podlega). Jak startuje mi program i wykonuje się jego funkcja zarejestrowana jako główna, to jest w takim przypadku jeden wątek. Jeśli spod tej funkcji, lub którejś dalej, wywołuje się pthread_create, to ten wątek jest nadrzędnym dla tego, co się w tym momencie tworzy. Z procesami i forkiem jest zresztą podobnie. Natomiast inna sprawa, gdy mamy do czynienia z modelem wątków zaproponowanym przez Maćka Sobczaka. Ale i tam model blokowania sygnałów musiałby być zupełnie inny - nie wykluczam, że prostszy. > Jeśli wątek miałby zakleszczyć się sam ze sobą, to odpowiednia operacja > rzuca wyjątkiem. No i ok. > Wzajemne zakleszczenie kilku wątków nie jest wykrywane, To mogłoby być trudne, chociaż nie wykluczam, że mogłoby to być możliwe. Program musiałby jednak mieć również jeden wątek kontrolny na takie okazje. Oczywiście pod warunkiem, że mówimy o zasobach jednostkowych (bo unix-owe funkcje typu semget pozwalają na zabieranie wielokrotne). > ale są reakcje na to, że wątek miałby zostać odśmiecony (co może być > skutkiem ich zakleszczenia, jeśli nikt inny nie ma dostępu do obiektów > synchronizujących, na których czekają) I jednocześnie nie mający dostępu do IO? > i na zakleszczenie wszystkich wątków. A tu - jak? W momencie zajęcia mutexu się to sprawdza? > > Tak - tu, jak najbardziej, ale napisałem wyraźnie: NIE odkładanie > > reakcji na przerwanie ad calendas graecas. > To jest kwestia przyzwoitości kodu, a nie gwarancji dawanych przez język. > Dobrym zwyczajem jest blokowanie sygnałów tylko na krótkie chwile, ale > nie da się tego wymusić. Zgadza się, co więcej, nawet w C++ da się zrobić tak, że w handlerze terminate() wywołasz main(). Ale fakt, że nie możesz normalnie kontynuować wykonania po otrzymaniu terminate() lub unexpected() stanowi już pewne określone utrudnienie. To stanowi zawsze odpowiednią sugestię. PS. Swoją drogą, zauważyłem że na wszystkich tutorialach - nie sprawdzałem dokładnie swojego pod tym względem, ale chyba jest chlubnym wyjątkiem :) - całkowicie ŹLE tłumaczą, jak wygląda obsługa nieoczekiwanego wyjątku i wyjątku poprzez main(), czyli sprawa unexpected() i terminate(). Funkcje set_terminate() i set_unexpected() nie służą do ustawiania własnych handlerów wykonujących się ZAMIAST domyślnych (to nie jest "szklanka zimnej wody jako środek antykoncepcyjny"). Handlery te wykonują się PRZED domyślną obsługą. Inaczej mówiąc: Wystąpienie nieoczekiwanego wyjątku powoduje wywołanie funkcji unexpected(). Wykonuje ona funkcję użytkownika, jeśli takową ustawiono przez set_unexpected(), a następnie wywołuje terminate(). Wypuszczenie wyjątku z funkcji main() bezpośrednio wywołuje terminate(). Wykonuje ona funkcję użytkownika, jeśli takową ustawiono przez set_terminate(), a następnie wywołuje abort(). -- // _ ___ Michal "Sektor" Malecki <sektor(whirl)kis.p.lodz.pl> \\ L_ |/ `| /^\ ,() <ethouris(O)gmail.com> // \_ |\ \/ \_/ /\ C++ bez cholesterolu: http://www.intercon.pl/~sektor/cbx "Java is answer for a question that has never been stated"
Technical Details
Message-ID:
<fj1tmo$52u$1@kujawiak.man.lodz.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!agh.edu.pl!news.agh.edu.pl!newsfeed.silweb.pl!news.man.lodz.pl!not-for-mailReferences:
<fghgeo$spf$1@nemesis.news.tpi.pl> <fghsb4$kpq$1@news.dialog.net.pl> <fgo4c7$mtu$1@news.vectranet.pl> <20071106073039.433f4934@Vorago> <fgqn9m$74j$2@news.vectranet.pl> <618565031.20071107113041@pkierski.net> <fgt6sh$jov$1@news.vectranet.pl> <fgtb6j$nur$1@news.vectranet.pl> <fgv6ba$k14$1@bozon2.softax.pl> <fgvkne$u3b$1@news.vectranet.pl> <fh1tjd$dtt$1@bozon2.softax.pl> <fh2lj6$qkh$1@news.vectranet.pl> <fha3as$pap$1@bozon2.softax.pl> <fhaj8u$e02$1@news.vectranet.pl> <fhf09d$ohq$1@bozon2.softax.pl> <fhfi9l$640$1@news.vectranet.pl> <fhurmu$5d9$1@bozon2.softax.pl> <fhv020$8k1$1@news.vectranet.pl> <fi1bs4$nn3$1@bozon2.softax.pl> <fi27ds$gt1$1@kujawiak.man.lodz.pl> <1195688300.8426.30.camel@qrnik> <fi3ems$7ig$1@kujawiak.man.lodz.pl> <1195734091.8426.77.camel@qrnik> <fi6n5f$fpr$1@kujawiak.man.lodz.pl> <1195858230.20523.107.camel@qrnik> <fie2un$cbn$1@kujawiak.man.lodz.pl> <1196076390.30869.52.camel@qrnik>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.rmf.pl!agh.edu.pl!news.agh.edu.pl!newsfeed.silweb.pl!news.man.lodz.pl!not-for-mail
From: Sektor van Skijlen <ethouris@guess.if.gmail.com.is.valid.or.invalid>
Newsgroups: pl.comp.lang.c
Subject: Re: Ciemna strona C++
Date: Mon, 3 Dec 2007 21:50:16 +0000 (UTC)
Organization: LODMAN - Metropolitan Area Network in LODZ, Poland
Lines: 156
Sender: Michal Malecki <sektor@student.kis.p.lodz.pl>
Message-ID: <fj1tmo$52u$1@kujawiak.man.lodz.pl>
References: <fghgeo$spf$1@nemesis.news.tpi.pl> <fghsb4$kpq$1@news.dialog.net.pl> <fgo4c7$mtu$1@news.vectranet.pl> <20071106073039.433f4934@Vorago> <fgqn9m$74j$2@news.vectranet.pl> <618565031.20071107113041@pkierski.net> <fgt6sh$jov$1@news.vectranet.pl> <fgtb6j$nur$1@news.vectranet.pl> <fgv6ba$k14$1@bozon2.softax.pl> <fgvkne$u3b$1@news.vectranet.pl> <fh1tjd$dtt$1@bozon2.softax.pl> <fh2lj6$qkh$1@news.vectranet.pl> <fha3as$pap$1@bozon2.softax.pl> <fhaj8u$e02$1@news.vectranet.pl> <fhf09d$ohq$1@bozon2.softax.pl> <fhfi9l$640$1@news.vectranet.pl> <fhurmu$5d9$1@bozon2.softax.pl> <fhv020$8k1$1@news.vectranet.pl> <fi1bs4$nn3$1@bozon2.softax.pl> <fi27ds$gt1$1@kujawiak.man.lodz.pl> <1195688300.8426.30.camel@qrnik> <fi3ems$7ig$1@kujawiak.man.lodz.pl> <1195734091.8426.77.camel@qrnik> <fi6n5f$fpr$1@kujawiak.man.lodz.pl> <1195858230.20523.107.camel@qrnik> <fie2un$cbn$1@kujawiak.man.lodz.pl> <1196076390.30869.52.camel@qrnik>
NNTP-Posting-Host: student.kis.p.lodz.pl
Mime-Version: 1.0
X-Trace: kujawiak.man.lodz.pl 1196718616 5214 212.191.89.21 (3 Dec 2007 21:50:16 GMT)
X-Complaints-To: abuse@man.lodz.pl
NNTP-Posting-Date: Mon, 3 Dec 2007 21:50:16 +0000 (UTC)
User-Agent: tin/1.8.3-20070201 ("Scotasay") (UNIX) (FreeBSD/6.2-RELEASE-p3 (sparc64))
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit