Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > pl.comp.programming > #33990 > unrolled thread
| Started by | Maciej Sobczak <see.my.homepage@gmail.com> |
|---|---|
| First post | 2020-06-08 14:58 -0700 |
| Last post | 2020-06-14 11:52 -0700 |
| Articles | 16 — 3 participants |
Back to article view | Back to pl.comp.programming
Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-08 14:58 -0700
Re: Integracja bibliotek event-based heby <heby@poczta.onet.pl> - 2020-06-09 00:32 +0200
Re: Integracja bibliotek event-based heby <heby@poczta.onet.pl> - 2020-06-09 00:38 +0200
Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-09 09:46 +0200
Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-09 13:58 -0700
Re: Integracja bibliotek event-based heby <heby@poczta.onet.pl> - 2020-06-09 23:18 +0200
Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-10 10:56 +0200
Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-10 14:19 -0700
Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-11 10:37 +0200
Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-11 11:00 -0700
Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-11 21:58 +0200
Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-12 11:55 -0700
Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-13 09:33 +0200
Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-13 12:52 -0700
Re: Integracja bibliotek event-based Mateusz Viste <mateusz@xyz.invalid> - 2020-06-14 13:55 +0200
Re: Integracja bibliotek event-based Maciej Sobczak <see.my.homepage@gmail.com> - 2020-06-14 11:52 -0700
| From | Maciej Sobczak <see.my.homepage@gmail.com> |
|---|---|
| Date | 2020-06-08 14:58 -0700 |
| Subject | Integracja bibliotek event-based |
| Message-ID | <5d642286-413d-47db-91b0-c689bbe167f4o@googlegroups.com> |
To jest wyciągnięty pod-wątek z wątku o serwerze HTTP.
Powiedzmy, że program używa 3 bibliotek event-based. Żeby nie trzeba było mieć wątków i innych muteksów.
W jednej trzeba zrobić server->next(), w drugiej agent.do_some_work() a w trzeciej worker::process(). Powiedzmy, że te funkcje od razu wychodzą jak nie mają nic do roboty, a jak mają, to szybko robią (bo na nic nie czekają) i też wychodzą.
Co należy zrobić, żeby użyć ich razem w jednym programie?
Takie coś:
while (true)
{
server->next();
agent.do_some_work();
worker::process();
}
jest złe, bo kręci się w kółko i zużywa prąd nawet (zwłaszcza) wtedy, gdy nie ma nic do zrobienia. Nie chcemy tak.
Jakie jest poprawne rozwiązanie dla integracji tych 3 bibliotek?
--
Maciej Sobczak * http://www.inspirel.com
[toc] | [next] | [standalone]
| From | heby <heby@poczta.onet.pl> |
|---|---|
| Date | 2020-06-09 00:32 +0200 |
| Message-ID | <rbmea1$76l$1@dont-email.me> |
| In reply to | #33990 |
On 08/06/2020 23:58, Maciej Sobczak wrote: > Jakie jest poprawne rozwiązanie dla integracji tych 3 bibliotek? To zależy co robią. Jeśli ich zadaniem jest coś policzyć i zniknąć to masz dobrze. Jesli ich zadaniem jest coś policzyć tylko jak będzie potrzeba to od tego masz wsparcie OSa i jego pętlę komunikatów. Być może też jakieś wątki pod spodem, ale klient o nich nie wie, bibliteka często też nie wie. Ogólnie cooperative multitasking bazuje na tym że robisz jak przychodzi jakiś event. Systemowy zazwyczaj. Można poprosić aby przychodził non-stop jeden za drugim. Każdemu w/g potrzeb. Oba podejścia są od dziesiątek lat katowane choćby w Qt i masz tam jakiś obraz tego jak zrobić 1) (onIdle()) i jak zrobić 2) (push event). Mogą z sobą działać bardzo gładko i elegancko. Mam duże (w sensie wielopoziomoe) algorytmy rozbite na pojednycze kroki i popychane z onIdle z głownej pętli. Spadek wydajności jest, ale pomijalny, choć oczywiscie wszystko zależy od tego jak realizowany jest yeld(). To podejście jest nie dla sztuki, tylko warunki brzegowe utrudniają użycie watków. Na szczęscie nie ma najmniejszego problemu, w dodatku mogę takie coroutines wrzucić *dynamicznie* do wątku i z niego wyjąć kiedy tylko chcę, na przykład w połowie pracy. Teoretycznie każdy algorytm można przerobić na coroutine za pomocą boost::context ale koszt może być wysoki, to wszak przełącza kontekst, prawie jak wątek. W przypadku ręcznym najczęściej pasuje jakiś wzorzec typu maszyn stanów. Do ogarnięcia w typowych przypadkach, rekurencja jest bardziej bolesna, ale niewiele.
[toc] | [prev] | [next] | [standalone]
| From | heby <heby@poczta.onet.pl> |
|---|---|
| Date | 2020-06-09 00:38 +0200 |
| Message-ID | <rbmel6$8v8$1@dont-email.me> |
| In reply to | #33993 |
On 09/06/2020 00:32, heby wrote:
> wie. Ogólnie cooperative multitasking bazuje na tym że robisz jak
> przychodzi jakiś event. Systemowy zazwyczaj. Można poprosić aby
> przychodził non-stop jeden za drugim. Każdemu w/g potrzeb.
z grubsza to jest tak:
std::vector< jobs > jobs;
Scheduler::onIdle()
{
if ( somethingToDo( jobs) )
{
sheduleNextOnIdleEvent();
doSomething( shuffle( jobs ) );
}
// stop onIdle callbacks by doing nothing
}
I to samoczynnie się zatrzyma jak coroutines zakończą pracę.
Mechanizm onIdle jest systemowy i jest drugorzędne jak działa.
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Viste <mateusz@xyz.invalid> |
|---|---|
| Date | 2020-06-09 09:46 +0200 |
| Message-ID | <20200609094640.04ee0ae2@mateusz> |
| In reply to | #33990 |
2020-06-08 o 14:58 -0700, Maciej Sobczak napisał:
> while (true)
> {
> server->next();
> agent.do_some_work();
> worker::process();
> }
>
> jest złe, bo kręci się w kółko i zużywa prąd nawet (zwłaszcza) wtedy,
> gdy nie ma nic do zrobienia. Nie chcemy tak.
Zdecydowanie nie chcemy. 30 lat temu na 386 to jeszcze uchodziło, bo
program był jeden na raz a i prądożernośćią CPU nikt się nie
przejmował. Dziś trochę wstyd, kiedy po uruchomieniu programu
wentylator w laptopie zaczyna się kręcić. :)
> Jakie jest poprawne rozwiązanie dla integracji tych 3 bibliotek?
To zależy co one mają robić. Skoro mowa o serwerze, to domniemywam że
punktem wejścia jest pojawienie się jakiegoś nowego stanu na
sockecie. Jeśli tak, to sprawa prosta:
for (;;) {
select(sockfd+1, &socksetr, &socksetw, &socksete, &timeout);
/* TODO obsługa SIGINT */
/* TODO obsługa timeout */
server->next();
agent.do_some_work();
worker::process();
}
Mateusz
[toc] | [prev] | [next] | [standalone]
| From | Maciej Sobczak <see.my.homepage@gmail.com> |
|---|---|
| Date | 2020-06-09 13:58 -0700 |
| Message-ID | <aa97820e-825e-4efe-b403-2c1f496dc7ffo@googlegroups.com> |
| In reply to | #33995 |
W dniu wtorek, 9 czerwca 2020 09:46:44 UTC+2 użytkownik Mateusz Viste napisał:
> > Jakie jest poprawne rozwiązanie dla integracji tych 3 bibliotek?
>
> To zależy co one mają robić.
Każda robi coś innego.
> Skoro mowa o serwerze, to domniemywam że
> punktem wejścia jest pojawienie się jakiegoś nowego stanu na
> sockecie.
Ale my nie widzimy tych socketów, bo one są ukryte w tych bibliotekach. Jedna obsługuje HTTP, druga asynchroniczną bazę danych a trzecia odbiera tweety z Twittera. Każda z nich ma zapewne jakieś sockety, ale nie wiemy o tym.
> Jeśli tak, to sprawa prosta:
>
> for (;;) {
> select(sockfd+1, &socksetr, &socksetw, &socksete, &timeout);
No więc wcale nie jest prosta, bo nie możemy zrobić tego selecta.
Możemy próbować to, co pokazał heby z onIdle i podobnymi, ale co jak mamy nie jedną, ale właśnie 3 biblioteki? Żadna z nich nie może zablokować żadnej z wywołanych funkcji (to jest błąd u heby[*]), bo to zatrzyma pętlę, a być może pozostałe biblioteki mają wtedy coś do zrobienia.
Więc gramy dalej. :-)
[*] Kurdę, łatwiej się odmienia "u Sebastiana", niż "u heby".
--
Maciej Sobczak * http://www.inspirel.com
[toc] | [prev] | [next] | [standalone]
| From | heby <heby@poczta.onet.pl> |
|---|---|
| Date | 2020-06-09 23:18 +0200 |
| Message-ID | <rboubi$ikv$2@dont-email.me> |
| In reply to | #33999 |
On 09/06/2020 22:58, Maciej Sobczak wrote: > Żadna z nich nie może zablokować żadnej z wywołanych funkcji (to jest błąd u heby[*]) To jest kontrakt. Jesli go złamiesz to masz problem. Więc to nie jest błąd, bo jeśli tak to taki sam błąd możesz zrobić w preemptive blokując muteks i wyrzucając klucz do kibla. > [*] Kurdę, łatwiej się odmienia "u Sebastiana", niż "u heby". To odmieniaj. Eternal Speptember randomicznie podpisuje mi maile, raz heby z adresu raz pełnym podpisem. Ch... wie dlaczego. Pewno nie mają unit testów ...
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Viste <mateusz@xyz.invalid> |
|---|---|
| Date | 2020-06-10 10:56 +0200 |
| Message-ID | <20200610105625.30b3dad0@mateusz> |
| In reply to | #33999 |
2020-06-09 o 13:58 -0700, Maciej Sobczak napisał: > Ale my nie widzimy tych socketów, bo one są ukryte w tych > bibliotekach. To jakieś strasznie opakowane te biblioteki, że nie pozwalają dobrać się do źródłowego socketa. > Jedna obsługuje HTTP, druga asynchroniczną bazę danych > a trzecia odbiera tweety z Twittera. Każda z nich ma zapewne jakieś > sockety, ale nie wiemy o tym. A co mówi dokumentacja tych bibliotek? Chyba ich autorzy nie zakładają, że ktoś będzie busy loop tworzył czekając na tweeta? Jeśli chodzi o asynchroniczną bazę danych, to klient wysłał jakieś polecenia i czeka na odpowiedź, jednocześnie robiąc coś innego. W takiej sytuacji wystarczy odczekać chwilę (np. pustym selectem) i sprawdzać jakimś db_isBusy() czy baza skończyła co miała robić. W zależności od założeń projektowych tę samą metodę można zastosować dla tweetów i "obsługi http" (cokolwiek by miało to znaczyć). Słowem - to samo co sugerowałem wcześniej, tyle że z pustym sockset w select() i sztywnym timeout, stosownie dobranym by niczego nie zakorkować. Ale to tylko jeśli biblioteki faktycznie nie udostępniają jakichkolwiek mechanizmów sygnalizacji swoich potrzeb. Mateusz
[toc] | [prev] | [next] | [standalone]
| From | Maciej Sobczak <see.my.homepage@gmail.com> |
|---|---|
| Date | 2020-06-10 14:19 -0700 |
| Message-ID | <e642682f-3296-4377-85b1-4c7dee0359b4o@googlegroups.com> |
| In reply to | #34006 |
> > Ale my nie widzimy tych socketów, bo one są ukryte w tych > > bibliotekach. > > To jakieś strasznie opakowane te biblioteki, że nie pozwalają dobrać > się do źródłowego socketa. Jest gorzej. To nie muszą być sockety. Np. system QNX ma fajny mechanizm komunikacji IPC, który istnieje poza przestrzenią deskryptorów plików. A ktoś inny będzie się komunikował przez pamięć dzieloną. Itd. Więc nawet gdybyś miał dostęp do bebechów, to i tak nie zapiąłbyś wszystkiego razem jednym selectem. No i nie możemy zakładać, że socket jest jeden, albo że ciągle ten sam, itd. Straszne komplikacje. > A co mówi dokumentacja tych bibliotek? To, co napisałem. Że wymienione funkcje robią robotę i wychodzą albo od razu wychodzą. > Chyba ich autorzy nie zakładają, > że ktoś będzie busy loop tworzył czekając na tweeta? Nie musi być busy loop. Bo możemy też założyć, że w każdej bibliotece jest dodatkowa funkcja wait_for_work(). Albo że te funkcje mają dodatkowy argument, żeby czekać. Tak jest w YAMI4. Wtedy pętla użytkownika nie musi być busy - po prostu blokuje się, jak nie ma nic do roboty. Ale mamy 3 takie funkcje. I co teraz? > W > takiej sytuacji wystarczy odczekać chwilę Dalej kiepsko, bo chcemy bez opóźnień przetwarzać zadania, jeśli są dostępne, i nie marnować prądu, jeśli nie są. > Ale to tylko jeśli biblioteki faktycznie nie udostępniają > jakichkolwiek mechanizmów sygnalizacji swoich potrzeb. Dobry trop. To w jaki sposób chciałbyś być poinformowany, że biblioteka ma potrzebę? Przypominam, że mamy 3 biblioteki. Przyjmijmy wersję idealną, że wszystkie 3 będą mieć ten mechanizm. Jaki? -- Maciej Sobczak * http://www.inspirel.com
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Viste <mateusz@xyz.invalid> |
|---|---|
| Date | 2020-06-11 10:37 +0200 |
| Message-ID | <20200611103732.69e48f11@mateusz> |
| In reply to | #34013 |
2020-06-10 o 14:19 -0700, Maciej Sobczak napisał: > Jest gorzej. To nie muszą być sockety. Np. system QNX ma fajny > mechanizm komunikacji IPC, który istnieje poza przestrzenią > deskryptorów plików. A ktoś inny będzie się komunikował przez pamięć > dzieloną. Trzymajmy się założeń: była mowa o bibliotece "do http", innej "do tweetera" i trzeciej "baza danych". Każda z nich raczej (?) opiera się na socketach. > No i nie możemy zakładać, że socket jest jeden, albo że ciągle ten > sam, itd. Straszne komplikacje. Jeśli jest ten sam to komplikacji nie ma - jeśli się urywa to biblioteka zwraca błąd i trzeba zainicjalizować na nowo. Jeśli natomiast socket się tworzy nowy przy każdym zawołaniu (np. sprawdzanie tweetów via nową sesję ssl za każdym razem), to każde sprawdzenia powinno być regularnie wywoływane przez program. > dodatkowy argument, żeby czekać. Tak jest w YAMI4. Wtedy pętla > użytkownika nie musi być busy - po prostu blokuje się, jak nie ma nic > do roboty. Po bardzo pobieżnym przejrzeniu rozumiem to tak, że inspirel oczekuje że stworzysz swój własny wątek specjalnie dla wołania ich biblioteki: "All activity has to be driven by the application, which is supposed to 'lease' one of its threads for doing the I/O work on behalf of the agent. This is achieved by calling the Do_Some_Work procedure in Ada or the do_some_work function in C++. The 'do some work' routine performs a single unit of work and returns to the caller. In a typical application it will be called in a tight loop." W takiej sytuacji niewiele można zrobić. Patrz niżej. > > Ale to tylko jeśli biblioteki faktycznie nie udostępniają > > jakichkolwiek mechanizmów sygnalizacji swoich potrzeb. > > Dobry trop. > To w jaki sposób chciałbyś być poinformowany, że biblioteka ma > potrzebę? > > Przypominam, że mamy 3 biblioteki. Przyjmijmy wersję idealną, że > wszystkie 3 będą mieć ten mechanizm. Jaki? Idealnie? No to chcę sam obsługiwać kanał danych (socket, IPC, whatever), a bibliotekę będę wołał tylko po to, żeby te dane obrobić/przetłumaczyć. Alternatywnie - niech biblioteka da dostęp do socketów, wówczas wiem, że jak coś się zmieni na kablu to powinien zawołać kogoś do obsługi. Ostatnia opcja: niech biblioteka da jakiś swój blokujący "wait_for_event()", sama niech blokuje w sposób eko-mądry i zależny od implementacji, a ja sobie ją wywołam w osobnym wątku. 3 biblioteki = 3 wątki, da się przeżyć. Mateusz
[toc] | [prev] | [next] | [standalone]
| From | Maciej Sobczak <see.my.homepage@gmail.com> |
|---|---|
| Date | 2020-06-11 11:00 -0700 |
| Message-ID | <9386ac2d-2d1d-46db-8f52-250c1511dfebo@googlegroups.com> |
| In reply to | #34014 |
> Trzymajmy się założeń: była mowa o bibliotece "do http", innej "do > tweetera" i trzeciej "baza danych". Nie. Była mowa o integracji kilku bibliotek event-based. Przykłady dot. HTTP, bazy danych i Twittera to były *przykłady* do zobrazowania problemu a nie konkretne zadania do rozwiązania. Właściwym problemem jest integracja bibliotek narzucających jakiś idiom czy wzorzec ich obsługi. > Każda z nich raczej (?) opiera się > na socketach. Nie. W szczególności biblioteka do baz danych automatycznie dobierze metodę komunikacji zależnie od tego, gdzie jest baza. W szczególności, jeśli baza jest na tym samym komputerze, to istnieją sprawniejsze metody komunikacji, niż sockety. Wyobraź sobie dla jeszcze szerszego spektrum, że jedna z tych bibliotek to zwykłe GUI, gdzie "gotowość" to event w kolejce, bo użytkownik coś kliknął. Czyli tu nie chodzi o sockety. Tu chodzi o integrację bibliotek. > > No i nie możemy zakładać, że socket jest jeden, albo że ciągle ten > > sam, itd. Straszne komplikacje. > > Jeśli jest ten sam to komplikacji nie ma - jeśli się urywa to > biblioteka zwraca błąd i trzeba zainicjalizować na nowo. Jeśli > natomiast socket się tworzy nowy przy każdym zawołaniu (np. sprawdzanie > tweetów via nową sesję ssl za każdym razem), to każde sprawdzenia > powinno być regularnie wywoływane przez program. Nie na temat, ale dalej źle. Przykładowo, YAMI4 może mieć tysiące socketów. Pomijając drobny fakt, że select() nie nadaje się do obsługi tysięcy socketów, biblioteka stosuje algorytmy control-flow decydujące o tym, który kanał w ogóle albo w danym momencie zasługuje na obsługę. Czyli z faktu, że wśród tysięcy socketów kilkaset ma dane gotowe do odczytu wcale nie wynika, że to jest stan gotowości do wykonania zadania, bo akurat te sockety z gotowymi danymi nie muszą mieć "zielonego światła" na ruch komunikatów i może się okazać, że wtedy nadal jest "idle". O tym decyduje biblioteka. Dlatego nie możesz się nastawiać na to, że będziesz sobie sam obserwował te sockety, bo i tak nie masz kontekstu do pełnej oceny sytuacji. Co więcej, jest kompletnie bez sensu, żebyś duplikował ciężką pracę, którą biblioteka i tak robi w środku. > > Przypominam, że mamy 3 biblioteki. Przyjmijmy wersję idealną, że > > wszystkie 3 będą mieć ten mechanizm. Jaki? > > Idealnie? No to chcę sam obsługiwać kanał danych (socket, IPC, > whatever), a bibliotekę będę wołał tylko po to, żeby te dane > obrobić/przetłumaczyć. Już ustaliliśmy (powyżej), że nie. > Ostatnia opcja: niech biblioteka da jakiś > swój blokujący "wait_for_event()", sama niech blokuje w sposób > eko-mądry i zależny od implementacji, a ja sobie ją wywołam w osobnym > wątku. 3 biblioteki = 3 wątki, da się przeżyć. Świetnie. Doszedłeś w ten sposób do wniosku, że do obsługi *kilku* bibliotek event-based potrzebne są wątki. Albo wyjdą z biblioteki albo do niej wejdą. Ale będą potrzebne. Głębsza analiza wygląda tak: Pojęcie "idle" lub "nie ma zadania", itp. to pojęcia *lokalne*, zrozumiałe tylko w obrębie jednej biblioteki. Tzn. w bibliotece GUI to pojęcie oznacza, że user nic nie kliknął, w bibliotece komunikacyjnej że nie ma komunikatu, w bibliotece do baz danych że nie ma jeszcze odpowiedzi na wcześniejsze zapytanie, itd. To są stany *lokalne*. Jeżeli program jest w całości oparty o rytm pracy *jednej* biblioteki (tak jak w prostym GUI opartym o zdarzenia z okna), to ten lokalny koncept jest też globalny, czyli dotyczy całego programu. Wtedy nie są potrzebne ani wątki, ani muteksy. Ale jeśli mamy kilka takich bibliotek, każda ze swoim własnym konceptem "idle", to ich integracja jest problemem, bo globalnie "idle" oznacza, że *nikt* nie ma nic do roboty a tego stanu nie da się uwspólnić w jednym wątku, bez ciężkich kompromisów typu kręcenie się w pętli z odpytywaniem (nawet z jakimś mniej lub bardziej przemyślanym opóźnieniem). Dlatego albo: 1. pozwolimy tym bibliotekom niezależnie informować o swoim bieżącym stanie przez callbacki wychodzące z tych bibliotek (w takim callbacku można np. odetkać główną pętlę czekającą na jakiejś fladze stopu) (co wymaga istnienia wątków w tych bibliotekach), albo 2. zrobimy sobie osobne wątki do kręcenia blokującymi pętlami dla każdej biblioteki osobno, albo 3. w ogóle schowamy ten koncept "idle" razem z pętlami zdarzeń i pozwolimy bibliotekom kręcić swoimi zdarzeniami samodzielnie (z własnych wątków). Tak czy inaczej mamy wątki. I ich konsekwencje. Ktoś ma pomysł na rozwiązanie tego problemu bez wątków? -- Maciej Sobczak * http://www.inspirel.com
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Viste <mateusz@xyz.invalid> |
|---|---|
| Date | 2020-06-11 21:58 +0200 |
| Message-ID | <20200611215852.33a1c421@mateusz> |
| In reply to | #34015 |
2020-06-11 o 11:00 -0700, Maciej Sobczak napisał: > > Trzymajmy się założeń: była mowa o bibliotece "do http", innej "do > > tweetera" i trzeciej "baza danych". > > Nie. Była mowa o integracji kilku bibliotek event-based. > Przykłady dot. HTTP, bazy danych i Twittera to były *przykłady* do > zobrazowania problemu a nie konkretne zadania do rozwiązania. No widzisz, ja nie zajmuję się akademickimi rozważaniami, staram się rozwiązywać wyłącznie praktyczne problemy. Było trafniejszy przykład dać. > Nie. W szczególności biblioteka do baz danych automatycznie dobierze > metodę komunikacji zależnie od tego, gdzie jest baza. W > szczególności, jeśli baza jest na tym samym komputerze Unix domain? Też socket. > to istnieją sprawniejsze metody komunikacji, niż sockety. "sprawniejsze" w tym kontekście jest niezwykle śmieszne. Nie słyszałem jeszcze o tym, by komukolwiek udało się odciążyć serwer bazodanowy poprzez zmianę kanału komunikacji na "sprawniejszy" (pomijam ew. głupoty jak silne ssl po localhost). To po prostu nie ma żadnego znaczenia. No ale rozumiem, że znów chodzi o to, że oczekiwałeś złotego rozwiązania na ogólny problem, a ja tu włażę w kaloszach i saperką. Idealista. > Pomijając drobny fakt, że select() nie nadaje się do obsługi tysięcy > socketów Użyj poll(). Względnie epoll(). > Co więcej, jest kompletnie bez sensu, żebyś duplikował ciężką pracę, > którą biblioteka i tak robi w środku. To zależy od konkretnego przypadku. Ciężka praca polegająca na otwarciu połączenia żeby sprawdzić tweetera nie jest tak znów ciężka. Przy innych rzeczach może być inaczej. > Doszedłeś w ten sposób do wniosku, że do obsługi *kilku* bibliotek > event-based potrzebne są wątki. Albo wyjdą z biblioteki albo do niej > wejdą. Ale będą potrzebne. Przy założeniu, że chcesz quasi-natychmiastowy czas reakcji, że biblioteka nie udostępnia socketa(ów), że nie pracujesz na żadnych przerwaniach sprzętowych oraz że nie chcesz busy loop z opóźnieniem (lub bez)... to tak. Wszystko zależy od założeń projektowych. > tego stanu nie da się uwspólnić w jednym wątku, bez ciężkich > kompromisów typu kręcenie się w pętli z odpytywaniem (nawet z jakimś > mniej lub bardziej przemyślanym opóźnieniem). "ciężki kompromis"? Bez przesady. Tak działał m.in. Win 3.x. I w praktyce bardzo fajnie mu wychodziło. Kwestia doboru timingu do akceptowalnego poziomu latencji oraz możliwości buforowych tego, co biblioteki mają obsłużyć. A jeśli ma być nowocześnie i szybko to wątki. No ale ty chcesz uniwersalny lek na zło całego świata. :) Mateusz
[toc] | [prev] | [next] | [standalone]
| From | Maciej Sobczak <see.my.homepage@gmail.com> |
|---|---|
| Date | 2020-06-12 11:55 -0700 |
| Message-ID | <5ecf1d89-86e9-4b98-b92b-f90a1c9a739ao@googlegroups.com> |
| In reply to | #34016 |
> > Nie. W szczególności biblioteka do baz danych automatycznie dobierze > > metodę komunikacji zależnie od tego, gdzie jest baza. W > > szczególności, jeśli baza jest na tym samym komputerze > > Unix domain? Też socket. https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.admin.doc/ids_admin_0133.htm No jednak nie socket. > > to istnieją sprawniejsze metody komunikacji, niż sockety. > > "sprawniejsze" w tym kontekście jest niezwykle śmieszne. Nie słyszałem > jeszcze o tym, by komukolwiek udało się odciążyć serwer bazodanowy > poprzez zmianę kanału komunikacji na "sprawniejszy" https://www.ibm.com/support/knowledgecenter/SSGU8G_14.1.0/com.ibm.admin.doc/ids_admin_0343.htm "The database server uses shared memory to [...] provide a fast communications channel for local client applications [...]." > No ale rozumiem, że znów chodzi o to, że oczekiwałeś > złotego rozwiązania na ogólny problem, a ja tu włażę w kaloszach > i saperką. Zapraszam również w kaloszach. > > Pomijając drobny fakt, że select() nie nadaje się do obsługi tysięcy > > socketów > > Użyj poll(). Względnie epoll(). Ani poll() ani epoll() nie działają z pamięcią dzieloną, którą Twój klient używa do sprawnej komunikacji z bazą danych na tym samym komputerze. > > Co więcej, jest kompletnie bez sensu, żebyś duplikował ciężką pracę, > > którą biblioteka i tak robi w środku. > > To zależy od konkretnego przypadku. Tak. W podanym przeze mnie konkretnym przypadku jest to bez sensu. > > Doszedłeś w ten sposób do wniosku, że do obsługi *kilku* bibliotek > > event-based potrzebne są wątki. > > Przy założeniu, że chcesz quasi-natychmiastowy czas reakcji, że > biblioteka nie udostępnia socketa(ów), że nie pracujesz na > żadnych przerwaniach sprzętowych oraz że nie chcesz busy loop z > opóźnieniem (lub bez)... to tak. Wszystko zależy od założeń > projektowych. Właśnie takie mam założenia projektowe. Bo można mieć też inne założenia projektowe - np. takie, że z założenia ma nie być wątków, niezależnie od ceny, którą trzeba będzie za ten brak wątków zapłacić. Wtedy oczywiście szukamy innych rozwiązań. Ogólnie - minimalizujemy koszt. > No ale ty chcesz uniwersalny lek na zło całego świata. :) Nie. Dyskutujemy sobie tylko, a kontakt z innym punktem widzenia pozwala też lepiej zrozumieć swój własny. -- Maciej Sobczak * http://www.inspirel.com
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Viste <mateusz@xyz.invalid> |
|---|---|
| Date | 2020-06-13 09:33 +0200 |
| Message-ID | <20200613093325.6a641a6c@mateusz> |
| In reply to | #34017 |
2020-06-12 o 11:55 -0700, Maciej Sobczak napisał:
> https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.admin.doc/ids_admin_0133.htm
Heh, Informix :) Nie wiedziałem, że to jeszcze istnieje. Ostatnio
słyszałem o tym co najmniej 20 lat temu. Z ciekawości zapytam - bo nie
znam - dlaczego ktoś wolałby Informix zamiast takiego np. PostgreSQL?
> No jednak nie socket.
No nie, bo to nie unix domain o którym pisałem, tylko pamięć
współdzielona. Między liniami czytając (i nie wgłębiając się zanadto w
ich dokumentację) rozumiem, że IBM proponuje zwyczajne korzystanie z
wątków ("poll threads for shared memory connections").
> "The database server uses shared memory to [...] provide a fast
> communications channel for local client applications [...]."
No właśnie. Po co ktoś miałby taką gimnastykę wykonywać w ramach
komunikacji *z bazą danych* jest poza moim zasięgiem zrozumienia, ale
umiem sobie wyobrazić, że ktoś się uparł i tak chce - bo tak.
> > Przy założeniu, że chcesz quasi-natychmiastowy czas reakcji, że
> > biblioteka nie udostępnia socketa(ów), że nie pracujesz na
> > żadnych przerwaniach sprzętowych oraz że nie chcesz busy loop z
> > opóźnieniem (lub bez)... to tak. Wszystko zależy od założeń
> > projektowych.
>
> Właśnie takie mam założenia projektowe.
Z podanych linków wnioskuję, że jesteś pośrednio lub bezpośrednio
klientem Informixa. Masz zatem pewnie dostęp do ichniego supportu
deweloperskiego - być może warto ich zapytać, co proponują przy takich
założeniach, bez użycia wątków? Ciekaw jestem odpowiedzi.
> Nie. Dyskutujemy sobie tylko, a kontakt z innym punktem widzenia
> pozwala też lepiej zrozumieć swój własny.
Ja prosty człowiek jestem, świat postrzegam w kategoriach bardzo
mechanicznych. To dotyczy również programowania. W omawianym
przykładzie mamy 3 pudełka, każde otwierane innym rodzajem klucza. W
tych pudełkach raz na jakiś czas pojawia się zawartość, którą należy
wyciągnąć żeby pudełko się nie zapchało. Pudełka są nieprzeźroczyste i
jedyną metodą sprawdzenia czy coś w nich jest, jest ich otwarcie za
pomocą specjalnego klucza. No to nie ma cudów: trzeba otwierać... I tu
do wyboru otwieranie/zamykanie sekwencyjnie w kółko jeden po drugim, lub
ew. postawienie przed każdym pudełkiem dedykowanego pracownika, który
przytrzymuje wieczko i czeka aż coś się pojawi. W mojej perspektywie
rzeczywistości nie ma innej drogi, no ale jeśli się mylę to chętnie się
dowiem.
Mateusz
[toc] | [prev] | [next] | [standalone]
| From | Maciej Sobczak <see.my.homepage@gmail.com> |
|---|---|
| Date | 2020-06-13 12:52 -0700 |
| Message-ID | <618ccdb2-d697-42f3-bf3d-7c0bb9b6e4c8o@googlegroups.com> |
| In reply to | #34020 |
> Heh, Informix :) Nie wiedziałem, że to jeszcze istnieje. https://docs.oracle.com/database/timesten-18.1/TTOPR/client_server.htm#TTOPR182 "Using a shared memory segment provides better performance than TCP/IP communication." To nie jest kwestia przestarzałego Informixa. > Z ciekawości zapytam - bo nie > znam - dlaczego ktoś wolałby Informix zamiast takiego np. PostgreSQL? Bo komuś się tak opłaca. W jakimś sensie tego słowa. [wracamy do pamięci dzielonej] > No właśnie. Po co ktoś miałby taką gimnastykę wykonywać w ramach > komunikacji *z bazą danych* jest poza moim zasięgiem zrozumienia, ale > umiem sobie wyobrazić, że ktoś się uparł i tak chce - bo tak. Nie. Tak jest naprawdę szybciej. Bo najszybsza komunikacja jest wtedy, gdy jej nie ma. W szczególności, jeśli dane w bazie istnieją w postaci jakiejś struktury, to tej struktury nawet nie trzeba serializować - wystarczy ją klientowi pokazać. Pakowanie danych do strumienia, po to żeby inny proces na tym samym komputerze te same dane sobie rozpakował, jest po prostu marnowaniem prądu. > Z podanych linków wnioskuję, że jesteś pośrednio lub bezpośrednio > klientem Informixa. Różne rzeczy widziałem na tej grupie w ciągu ostatnich dni, ale tym zrobiłeś mi weekend. :-) Nie mam o tym bladego pojęcia. Do szukania linków używam Google'a - i też nie jestem ich klientem (chociaż w tym przypadku pewnie jestem nawet jeśli o tym nie wiem). > Ja prosty człowiek jestem, świat postrzegam w kategoriach bardzo > mechanicznych. To dotyczy również programowania. W omawianym > przykładzie mamy 3 pudełka, każde otwierane innym rodzajem klucza. W > tych pudełkach raz na jakiś czas pojawia się zawartość, którą należy > wyciągnąć żeby pudełko się nie zapchało. I to też sobie wczoraj uświadomiłem, że jakoś niechcący wpadliśmy w narrację, że z tych gniazdek (albo nie-gniazdek) się tylko czyta. Ale przecież nawet ta biblioteka do Twittera nie musi tylko czytać (albo w ogóle nie musi czytać), może natomiast pisać. Znaczy - wysyłać tweety. Np. co godzinę. Są nawet takie konta na Twitterze, gdzie jakiś automat coś pluje co jakiś czas. No więc mamy gniazdo, powiedzmy nawet że się do niego dobraliśmy łamiąc zasady enkapsulacji i robimy na nim select() (czy tam inny poll) i dowiadujemy, się, że gniazdo jest gotowe do pisania. Hura! I co z tego wynika, że jest gotowe do pisania? Ano nic nie wynika. Bo to biblioteka decyduje, czy ma coś do pisania, a nie użytkownik, który dobrał się jej do gniazda. Więc gotowość gniazda wcale nie świadczy o tym, że jest jakiś inkrement pracy do wykonania. > I tu > do wyboru otwieranie/zamykanie sekwencyjnie w kółko jeden po drugim, lub > ew. postawienie przed każdym pudełkiem dedykowanego pracownika, który > przytrzymuje wieczko i czeka aż coś się pojawi. W mojej perspektywie > rzeczywistości nie ma innej drogi, Też się do tego wniosku skłaniam. -- Maciej Sobczak * http://www.inspirel.com
[toc] | [prev] | [next] | [standalone]
| From | Mateusz Viste <mateusz@xyz.invalid> |
|---|---|
| Date | 2020-06-14 13:55 +0200 |
| Message-ID | <20200614135509.1856260f@mateusz> |
| In reply to | #34021 |
2020-06-13 o 12:52 -0700, Maciej Sobczak napisał: > "Using a shared memory segment provides better performance than > TCP/IP communication." Jasne, ale już pisałem - bez sensu. To jak jeżdżenie z wyłączonymi światłami w samochodzie dla oszczędzania paliwa, mając V16 turbo pod maską. > Pakowanie danych do strumienia, po to żeby inny proces na tym samym > komputerze te same dane sobie rozpakował, jest po prostu marnowaniem > prądu. Idąc tym tropem, to pisanie w C jest marnowaniem prądu - powinniśmy trzaskać wyłącznie goły ASM. :) No i baza danych SQL to też poroniony pomysł, przecież te wszelkie SELECTy, JOINy itd trzeba przeanalizować, zrozumieć, przetworzyć... Ileż to prądu! Użycie socketa w tym wszystkim to pikuś. > Różne rzeczy widziałem na tej grupie w ciągu ostatnich dni, ale tym > zrobiłeś mi weekend. :-) > > Nie mam o tym bladego pojęcia. > Do szukania linków używam Google'a - i też nie jestem ich klientem > (chociaż w tym przypadku pewnie jestem nawet jeśli o tym nie wiem). Entuzjastycznie założyłem, że podajesz w końcu jakiś prawdziwy przypadek, a nie że przeszukałeś internet żeby na siłę znaleźć "chcę wysyłać selecty via shmem". Faktycznie, mój błąd. Mateusz
[toc] | [prev] | [next] | [standalone]
| From | Maciej Sobczak <see.my.homepage@gmail.com> |
|---|---|
| Date | 2020-06-14 11:52 -0700 |
| Message-ID | <10cfa09f-7d5a-43c3-8798-16fb085044c6o@googlegroups.com> |
| In reply to | #34022 |
> > "Using a shared memory segment provides better performance than > > TCP/IP communication." > > Jasne, ale już pisałem - bez sensu. To jak jeżdżenie z wyłączonymi > światłami w samochodzie dla oszczędzania paliwa, mając V16 turbo pod > maską. A skąd to porównanie? Jeżeli aplikacja potrzebuje odebrać z bazy np. 1GB danych, to zamiast przesyłać te dane przez gniazda, lepiej ich w ogóle nie przesyłać. > Idąc tym tropem, to pisanie w C jest marnowaniem prądu - powinniśmy > trzaskać wyłącznie goły ASM. :) Niektórzy swoje programy w C kompilują. > No i baza danych SQL to też poroniony pomysł, przecież te wszelkie > SELECTy, JOINy itd trzeba przeanalizować, zrozumieć, przetworzyć... > Ileż to prądu! Użycie socketa w tym wszystkim to pikuś. Ale masz na to jakieś dane? Liczby? Jeżeli robisz proste zapytanie na dużą ilość danych, to jakie będą proporcje? > Entuzjastycznie założyłem, że podajesz w końcu jakiś prawdziwy > przypadek, Prawdziwy przypadek to YAMI4, wymieniony już przeze mnie w tej dyskusji. Jednym z jego protokołów jest "qnx://", który w ogóle nie opiera się na gniazdach, a jest, razem z innymi protokołami, objęty obsługą w jednej funkcji do_some_work(). > a nie że przeszukałeś internet żeby na siłę znaleźć Ja mam wrażenie, że w ciągu ostatnich paru dni najwięcej prądu na tej grupie poszło dzięki grupowiczom, którzy na siłę szukają metody, żeby być "przeciw". A jeśli szukam czegoś w internecie, to przykładów potwierdzających moje argumenty - z nadzieją, że te argumenty stają się wtedy bardziej obiektywne. -- Maciej Sobczak * http://www.inspirel.com
[toc] | [prev] | [standalone]
Back to top | Article view | pl.comp.programming
csiph-web