Article View: pl.comp.lang.c
Article #267788Re: Ciemna strona C++
From: Sektor van Skijlen
Date: Fri, 23 Nov 2007 14:13
Date: Fri, 23 Nov 2007 14:13
185 lines
10915 bytes
10915 bytes
Dnia Thu, 22 Nov 2007 13:21:31 +0100, Marcin ?Qrczak? Kowalczyk skrobie: > Dnia 22-11-2007, Cz o godzinie 08:30 +0000, Sektor van Skijlen pisze: > > W praktyce to oznacza, że w którymś momencie MUSISZ po prostu > > najzwyczajniej w świecie obsłużyć ten wyjątek i nie ma od tego > > ucieczki. > W którymś momencie tak, ale lepiej nie przy każdym sleepie osobno, > tylko zbiorczo w głównej funkcji wątku. Momencik. Na pewno masz rację. I bardzo chętnie bym to zrobił, tylko nie w sytuacji, gdy InterruptedException nie jest pochodną RuntimeException, więc z jednego głupiego sleep() muszę go przepropagować przez całą ścieżkę. Ciekaw jestem swoją drogą, czy nie kończy się to czasem tym, że programiści wkurzeni koniecznością definiowania propagacji po prostu każą się wątkowi ukryć "pod osią ciężarówki RuntimeException". > > > Mam rozumieć, że lepiej, kiedy sprzątanie przez wątek po jego przerwaniu > > > > Stop! Nie mówimy tutaj o przerwaniu wyjątku. Mówiłem o zrobieniu sleep. > O przerwaniu wątku, a nie wyjątku. Taaa... już mi się wszystko plącze :) > Sleep jest jedną z funkcji, > która reaguje na przerwanie wątku z zewnątrz (Thread.interrupt). > Stąd możliwość InterruptedException. Super! Tylko po jasną cholerę mam w związku z tym deklarować propagację przez wszystkie możliwe funkcje? > Nie należy pisać tak jak napisałeś (połykać InterruptedException). > http://www-128.ibm.com/developerworks/java/library/j-jtp05236.html Dla mnie ideałem byłoby, gdyby w funkcji głównej wątku, lub w funkcji startującej aplikację (bo wątek przerywalny to również wątek główny, startujący aplikację) można było objąć cały kod trajem, jeśli trzeba jakoś specjalnie zareagować na nakaz zakończenia. Oczywiście prawda jest też taka, że gdybym miał C++ z biblioteką wątków i taki wątek byłby kończony za pomocą rzucenia wyjątku, to nie musiałbym właściwie (teoretycznie) robić niczego, nic się nawet nie stanie jak nie przechwycę wątku w ogóle. Wszystko mi zrobią destruktory. Natomiast w takiej np. Javie być może istnieje potrzeba przechwycenia tego wyjątku gdzieś w środku, żeby po prostu wykonało się odpowiednie finally. Co jest właściwie tożsame z wywołaniem destruktora w C++, tyle że w Javie trzeba to zrobić ręcznie. Oddzielną sprawą jest jednak sensowność kończenia wątku wyjątkiem. Ja sobie ten wyjątek mogę gdzieś w środku przechwycić. Jak nie przemierzając w podanym przykładzie. Wypadałoby ten wyjątek spropagować, ewentualnie na odpowiednim poziomie zakończyć wątek. Jak biblioteka wątków chciałaby mnie zmusić do tego, żeby nie "przechwytywać wyjątku na daremno"? > Pewnym odpowiednikiem tego w SUS są funkcje, które są przerywane przez > pthread_cancel w stanie PTHREAD_CANCEL_DEFERRED + PTHREAD_CANCEL_ENABLE > (domyślnym zresztą): > http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html#tag_02_09_05_02 > Jedno i drugie jest raczej sztuczką niż porządnym projektem językowym. Nie do końca. > Ponieważ te języki nie dostarczają mechanizmów pozwalających > programiście informować, w których momentach można przerwać wątek, > domyślnie zakłada się, że można to zrobić wtedy, kiedy wątek na coś > czeka (ale nie na mutex). Bo po pierwsze jest szansa, że takie momenty > będą zdarzały się wystarczająco często, a po drugie jest szansa, że > wszelkie niezmienniki globalnych struktur danych będą wtedy zachowane. Zgadza się, ale w stan sleep można wprowadzić wątek nie tylko wywołując sleep (mówię w sensie systemowo-ogólnym), ale również w stanie oczekiwania na I/O. Tymczasem w Javie InterruptedException jest rzucane tylko przez Thread.sleep i Object.wait. InputStream.read przykładowo rzuca tylko IOException! > Różnica między Javą a Uniksem polega w tym miejscu na tym, że Java > zmusza programistów do zauważenia, że dana funkcja jest przerywalna, > a Unix nie. Super - tylko skoro wątek może być przerwany tylko przez InterruptedException, to w jaki sposób następuje "killowanie" wątku javowego? Jeśli nikt nie używa żadnego sleep() w środku, to wątku nie można przerwać w ogóle? A jeśli można, to jak się to odbywa? > W połączeniu ze sprawą odśmiecania powoduje to, że > w Uniksowym C/C++ pthread_cancel ma małe szanse poprawnego działania. > Większość programistów nawet nie wie, że taka funkcja istnieje, i nie > pisze kodu tak żeby działał poprawnie w obliczu asynchronicznych > przerwań. Jeśli mówimy o GNU pthreads i GCC/C++ to podobno działają poprawnie, bo używany jest w pthread_cancel ten sam mechanizm, co w wyjątkach w C++. > Zgadzam się, że checked exceptions powodują z reguły więcej kłopotu niż > pożytku, ale z tego nie wynika, że jest w nic samo zło. Jest wystarczająco dużo tego zła, żeby stwierdzić, że ten ficzer jest porażką. > > Bo jeśli mówimy o normalnym przerwaniu wykonywania się wątku, to > > w takim razie powinien on teoretycznie wystąpić w dowolnym momencie. > > Nie tylko jak się wykonuje sleep(). > Gdyby mógł wystąpić w zupełnie dowolnym momencie, to nie dałoby się > pisać poprawnego kodu, bo np. nie da się zagwarantować, że z pewnych > dwóch instrukcji wykonają się obie albo żadna. Oj, nie rozumiem, niby dlaczego. Jeśli wykonuję a + b + c, a drugi plus rzuci wyjątkiem (bo akurat ktoś stwierdził, że sprzeda procesowi killa), to jaki problem tu może wystąpić? W C++ mógłby ci tutaj wystąpić problem ze wskaźnikami i nowo utworzonymi obiektami. No, jeśli chciałbyś mieć 100% exception-safe kod, to należałoby używać wyłącznie auto_ptr do przechowywania tymczasowej wartości wskaźnika na obiekt. Chyba że w danej funkcji panuje taka zasada, że w razie wyjątku i tak kończymy aplikację (i masz pewność, że system zwolni wszystkie zasoby przydzielone przez proces). Trochę inna sprawa występuje w przypadku, gdyby chcieć wspierać semantykę wznowienia - ale właśnie wspomniałem o tym, że semantyka wznowienia powinna być maksymalnie utrudniona. Na przykład tak, że każda funkcja systemowa (jakimś sposobem) rzuca wyjątkiem za każdym wywołaniem, jeśli proces już raz dostał killa. > Należy umożliwić wątkowi blokowanie przerywania Nie. Należy umożliwić wątkowi sprzątanie istniejących zasobów w razie przerwania, natomiast na pewno nie odkładanie reakcji na przerwanie ad calendas graecas. > oraz zintegrować > automatyczne blokowanie z innymi konstrukcjami języka (większość > programistów nie myśli o możliwości przerwania wątku i tego nie > zmienimy). Jeśli się postarać, jeśli język ma szansę rozpoznać > regiony, które muszą się wykonać w całości, w sposób niewymagający > od programisty dużego zachodu, to można domyślnie dopuścić przerywanie > w dowolnym momencie. Tak - a to z kolei wymaga oznaczenia obszarów, na terenie których następuje niestabilność stanu aplikacji. Ale wtedy można bez problemu przerwać to wyjątkiem. > Przy czym w C++ nie ma na to szans, bo jest zdecydowanie zbyt wiele > miejsc, których nie można przerwać, ale nie ma jak ich automatycznie > rozpoznać. Na przykład region między new a przypisaniem gołego wskaźnika > do sprytnego wskaźnika nie może być przerywalny (przynajmniej przy > standardowym alokatorze). Moment - o ile ja znam C++, to przerwanie przez wyjątek może nastąpić tylko w dwóch miejscach: w operatorze new (wtedy pamięć jest automatycznie usuwana) lub po przypisaniu (zakładamy, że w trakcie przypisywania nie wystąpi). Jeśli przerywamy wątek wyjątkiem, to tak powinno to działać. Ale nie mam pomysłu, jak to zorganizować. > > > > Natomiast "łatwe języki" zwykle dają złudzenie łatwości tematu w przypadku > > > > trudnych zagadnień. Jednym z takich trudnych zagadnień jest wielowątkowość. > > > > > Dawałyby takie złudzenie gdyby ułatwiały projekt, który z pewnych > > > subtelnych powodów jest niepoprawny, w porównaniu do poprawnego > > > projektu, który miałby trudniej z winy języka. Ale nie przypominam > > > sobie takich cech różnych języków, więc nie wiem, co masz na myśli. > > > > Same wątki w Javie już wystarczą. Nadużywa się ich, zamiast zrobić to samo na > > włóknach. > Uważasz, że lepiej wprowadzać sztuczne utrudnienia w używaniu wątków, > żeby zniechęcać do nich programistę? Uważam, że należy wspierać alternatywne rozwiązania i wskazywać ich zalety. I nie doradzać wątków do wszelkiej równoległej pracy, lecz właśnie wskazywać, dlaczego one się do równoległej pracy na jednym obiekcie nie nadają. -- // _ ___ 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:
<fi6n5f$fpr$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>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: Fri, 23 Nov 2007 14:13:03 +0000 (UTC)
Organization: LODMAN - Metropolitan Area Network in LODZ, Poland
Lines: 185
Sender: Michal Malecki <sektor@student.kis.p.lodz.pl>
Message-ID: <fi6n5f$fpr$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>
NNTP-Posting-Host: student.kis.p.lodz.pl
Mime-Version: 1.0
X-Trace: kujawiak.man.lodz.pl 1195827183 16187 212.191.89.21 (23 Nov 2007 14:13:03 GMT)
X-Complaints-To: abuse@man.lodz.pl
NNTP-Posting-Date: Fri, 23 Nov 2007 14:13:03 +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