abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 18:00 | IT novinky

    DuckDuckGo AI Chat umožňuje "pokecat si" s GPT-3.5 Turbo od OpenAI nebo Claude 1.2 Instant od Anthropic. Bez vytváření účtu. Všechny chaty jsou soukromé. DuckDuckGo je neukládá ani nepoužívá k trénování modelů umělé inteligence.

    Ladislav Hagara | Komentářů: 0
    dnes 14:22 | IT novinky

    VASA-1, výzkumný projekt Microsoftu. Na vstupu stačí jediná fotka a zvukový záznam. Na výstupu je dokonalá mluvící nebo zpívající hlava. Prý si technologii nechá jenom pro sebe. Žádné demo, API nebo placená služba. Zatím.

    Ladislav Hagara | Komentářů: 2
    dnes 04:44 | Nová verze

    Nová čísla časopisů od nakladatelství Raspberry Pi: MagPi 140 (pdf) a HackSpace 77 (pdf).

    Ladislav Hagara | Komentářů: 0
    dnes 01:00 | Nová verze

    ESPHome, tj. open source systém umožňující nastavovat zařízení s čipy ESP (i dalšími) pomocí konfiguračních souborů a připojit je do domácí automatizace, například do Home Assistantu, byl vydán ve verzi 2024.4.0.

    Ladislav Hagara | Komentářů: 0
    včera 22:11 | IT novinky Ladislav Hagara | Komentářů: 0
    včera 20:55 | Nová verze

    Neziskové průmyslové konsorcium Khronos Group vydalo verzi 1.1 specifikace OpenXR (Wikipedie), tj. standardu specifikujícího přístup k platformám a zařízením pro XR, tj. platformám a zařízením pro AR (rozšířenou realitu) a VR (virtuální realitu). Do základu se z rozšíření dostalo XR_EXT_local_floor. Společnost Collabora implementuje novou verzi specifikace do platformy Monado, tj. open source implementace OpenXR.

    Ladislav Hagara | Komentářů: 2
    včera 17:22 | Nová verze

    Byla vydána nová verze 0.38.0 multimediálního přehrávače mpv (Wikipedie) vycházejícího z přehrávačů MPlayer a mplayer2. Přehled novinek, změn a oprav na GitHubu. Požadován je FFmpeg 4.4 nebo novější a také libplacebo 6.338.2 nebo novější.

    Ladislav Hagara | Komentářů: 13
    včera 17:11 | Nová verze

    ClamAV (Wikipedie), tj. multiplatformní antivirový engine s otevřeným zdrojovým kódem pro detekci trojských koní, virů, malwaru a dalších škodlivých hrozeb, byl vydán ve verzích 1.3.1, 1.2.3 a 1.0.6. Ve verzi 1.3.1 je mimo jiné řešena bezpečnostní chyba CVE-2024-20380.

    Ladislav Hagara | Komentářů: 2
    včera 12:11 | IT novinky

    Digitální a informační agentura (DIA) oznámila (PDF, X a Facebook), že mobilní aplikace Portál občana je ode dneška oficiálně venku.

    Ladislav Hagara | Komentářů: 10
    včera 05:11 | Komunita

    #HACKUJBRNO 2024, byly zveřejněny výsledky a výstupy hackathonu města Brna nad otevřenými městskými daty, který se konal 13. a 14. dubna 2024.

    Ladislav Hagara | Komentářů: 2
    KDE Plasma 6
     (68%)
     (11%)
     (2%)
     (20%)
    Celkem 566 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

    Dotaz: Spravne ukoncenie multithread aplikacie - architektura

    25.9.2019 16:05 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Spravne ukoncenie multithread aplikacie - architektura
    Přečteno: 944×
    Caute, uz dlhsie riesim genericku zahadu v architekture SW (resp. design pattern). Predstavme si, ze mame multithread aplikaciu, ktora pouziva nejake mutexy, semafory, atd. Naraz pride event od uzivatela, ze chce aplikaciu ukoncit. Otazka znie, ako spravne uvolnit prostriedky, najma mutexy.

    Moje riesenie:
    1. volatile globalna premenna (event): "process_end"
    2. pocitadlo referencii pracovnych vlakien (atomic_inc pri vytvoreni vlakna, atomic_dec pri ukonceni vlakna)
    
    3. pracovne vlakno nemoze byt vytvorene, ak process_end == 1 (stale je tu race condition, ked otestujeme premennu process_end == 0, a nasledne vytvorime vlakno, no v medzikroku sa vsak process_end nastavi na 1)
    4. pracovne vlakno pred cakanim na mutex otestuje, ci process_end == 1, ak ano, ukoncuje sa
    5. hlavne vlakno caka v cykle na dekrement poctu vlakien do nuly (tu treba nejaky timeout)
    6. hlavne vlakno uvolnuje mutexy
    Existuje nejake ine, elegantnejsie riesenie, bez race conditions a bez potreby timeoutu? Moja (idealna) predstava je nasledovna:
    1. hlavne vlakno uvolni mutexy (pocitadlo referencii na mutex v kerneli vsak vie, ze ine vlakna este mutex vlastnia alebo cakaju nan)
    2. pracovne vlakno pri mutex_lock dostane return value "MUTEX_RELEASED" a prejde k svojmu ukonceniu, v ktorom dekrementuje ref_count na pocet vlakien
    3. hlavne vlakno po uvoleneni mutexov caka na dekrement poctu vlakien do 0.
    Tento design vsak pouzit so sucasnym navrhom mutexov, spinlockov, atd. nemozno pouzit.

    Odpovědi

    25.9.2019 16:38 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura

    Volatile v souvislosti s mutithreadingem je vždy chyba, nepoužívej volalile pro synchronizaci, nefunguje to. Volatile se prakticky používá pouze k přímému přístupu k hardware (HW registry mapované do paměti).

    Neexistuje jediné obecné řešení, záleží na konkrétním designu tvé aplikace. Obvykle se to dělá tak, že máš nějaký main thread, který zpracovává eventy a pak jednotlivé workery (thready), kterým se z main threadu přiděluje práce. Potom je to jednoduché, main thread dostane event, že se má aplikace ukončit a vyřídí ho. Pokud workery spí, nastaví jim příznak, že mají skončit a probudí je. Každý worker se po probuzení na ten přiznak podívá a pokud se má ukončit, tak skončí. Main thread pak jen udělá join na všechny workery. Pokud workery nespí a něco dělají, je to v zásadě stejné, main thread jim nastaví příznak k ukončení a zase udělá join na všechny workery. Je pak zodpovědnost workera, aby ten příznak čas od času zkontroval a ukončil se.

    Pokud ale máš nějaký zásadně jiný design aplikace, tak to budeš muset udělat nějak jinak.

    xkucf03 avatar 25.9.2019 18:57 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura

    Souhlas, akorát:

    Je pak zodpovědnost workera, aby ten příznak čas od času zkontroval a ukončil se.

    tady se to může zaseknout na nějaké síťové operaci a ta může trvat i dost dlouho. Není nějaká možnost, jak v rámci procesu vyvolat výjimku/chybu na všech síťových spojeních a tím to ukončit dřív?

    Na druhou stranu, tohle je pak zase v rozporu požadavkem na konzistenci. To čekání na konec síťové operace má svůj smysl a jen tak ta spojení pozabíjet může nadělat škody.

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    4.10.2019 06:24 ehmmm
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Co to je dlouho? Ja to treba delam tak, ze ten main ostatni thready zdvorile pozada, aby skoncili a pokud neposlechnou, tak je po napr. 30 sekundach ustreli.

    Co se tyka sitoych operaci, tak tam mam osobne problem akorat s timeouty TCP. Ale moje aplikace jsou obvykle provozovane po lokalnim ethernetu, takze timeouty nastavuji v jednotkach sekund.
    xkucf03 avatar 4.10.2019 08:32 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura

    Pamatuji si třeba DB klienta s Oracle ovladačem, kde když se rozpadlo síťové spojení (třeba po uspání nebo i jinak), tak to trvalo klidně i několik minut, než to vzdal a prohlásil spojení za neplatné a umožnil se připojit znova. Do té doby byla aplikace nepoužitelná, takže ji uživatel většinou celou natvrdo sestřelil a spustil znova, což bylo rychlejší.

    Chápu, že je za tím snaha dokončit případnou transakci a neztratit data předčasným/násilným odpojením, ale z hlediska UI to bylo dost špatné, protože to neumožňovalo okamžité odpojení na žádost uživatele (i za cenu případné ztráty dat z poslední transakce).

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    10.10.2019 08:26 rich
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Odpovidajici nastaveni pro klienta i server viz. sqlnet.ora
    4.10.2019 15:09 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Není nějaká možnost, jak v rámci procesu vyvolat výjimku/chybu na všech síťových spojeních a tím to ukončit dřív?
    Asi by například šlo všechny socket fd dávat do nějakýho globálního kontejneru a při ukončování na případný zbylý sockety zavolat shutdown() (a příp. close()) ...
    26.9.2019 00:06 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Takze,

    1. volatile sa nepouziva pre synchronizaciu, ale pre dorucenie spravy (eventu). Toho eventu (priznaku), ktory spominas ("nastavi jim przinak, ze maji skoncit a probudi je"). Ten priznak by mal byt volatile kvoli kompilatoru.

    2. "Pokud workery spí, nastaví jim příznak, že mají skončit a probudí je." A tu je prave cely problem. Ako ich prebudi? Ak worker thread caka na mutex, neprebudi. Je to presne ten pripad, ktory som popisoval, ze ak worker thread caka na mutex (napriklad), idealne by ho bolo potrebne prebudit tak, aby worker thread mutex neziskal, ale rovno mu bolo oznamene, ze worker thread sa ma ukoncit. Lenze takto mutex nefunguje.

    Tvoj navrh je presne ten, co som popisoval na zaciatku- neriesitelny z hladiska toho, ako funguju synchronizacne primitiva.

    26.9.2019 05:58 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Volatile nelze použít pro doručení zprávy do jiného threadu, není to sychronizační primitivum, nefunguje to. Už jsem ti to jednou psal a píšu znovu. Volatile nedělá sychronizaci mezi thready, není tam žádná memory bariéra, není zaručeno, že ten druhý thread uvidí aktuální hodnotu proměnné. Použij atomickou proměnnou, ne volatile.

    Pokud ti worker dlouhodobě čeká na mutex, máš tam nějakou designovou chybu, tohle by se stávat nemělo, mutexy se používají ke krátkodobému přístupu ke sdíleným prostředkům. Spící thread obvykle čeká na condition variable s odemčeným mutexem. Podívej se na std::condition_variable, tohle potřebuješ. Workera probudíš pomocí notifikace condition variable.
    26.9.2019 11:51 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    S tym, ze tam nie je memory barriera je sice pravda, ale skusim to vysvetlit inak. Ten volatile nepouzivam na SYNCHRONIZACIU, t.j. nie je velmi podstatne pre beh aplikacie memory ordering, co sa tyka tejto premennej. Ale suhlasim, ze nie je ani zarucene, ze instrukcia neprejde cez store working set v ALU v dostatocnom case, aj ked to je vzhladom na workflow instrukcii v CPU nepravdepodobne, ked hovorime dokonca o stovkach milisekund. Ale dobre, nech sa nehadame, povedzme, ze to zabezpecim cez atomic, ved to nie je jadro problemu.

    Teraz ku condition variable. Neviem, ako si to myslel, ale cakanie na condition variable vyzaduje cakanie na event. Na jeden event. Inak povedane, ak cakam na condition variable "data ready", nemozem cakat na condition "end of process". Alebo mozem- a tu sa dostavame prave k tomu design patternu: Chces povedat, ze process by mal zhromazdit vsetky mozne conditional variables, ktore mozu blokovat thready, do kontajnera a v pripade, ze sa ukonci proces, vsetky signalizovat?
    26.9.2019 12:35 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura

    Volatile používáš k předání informace do jiného threadu, ale to je úplně blbě, k tomu volatile neslouží a nebude to spolehlivě fungovat. Volatile použité v souvislosti s multithreadingem je prakticky vždy chyba.

    Nějak tomu workeru musíš předat informaci o tom, že se má ukončit. Je pak zodpovědností workera, že se opravdu ukončí. K předání informace o ukončení stačí nějaký bool flag (atomic nebo obyčejná proměnná pod mutexem). Worker ten flag musí čas od času zkontrovat, to je taky jeho zodpovědnost. Pokud je worker uspaný (nemá co dělat, čeká na práci), tak je zodpovědností main threadu, který mu práci přiděluje, aby ho probudil. No a worker si po probuzení zkontroluje, zda se má ukončit. Condition variable se používá k signalizaci workeru, že má něco dělat. Co konkrétně worker udělá, to už condition variable neřeší, to je věc implementace.

    Elementární příklad: https://pastebin.com/EjuxC0zB

    26.9.2019 16:55 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Ano, prave o tom vravim, takto som to vzdy riesil. Takze este raz. V tvojom priklade mas 1 cond. variable. V praxi tych cond. variables moze byt viac a vlakno moze cakat na 1 konkretnu podmienku (bezny pripad). Tento design pattern hovori prave o tom, ze pri ukoncovani vlakna by sme mali ocakavat, ze:
    1. worker thread moze cakat na rozne eventy a tieto eventy prebudit
    1.1 main thread by mal signalizovat vsetky tieto eventy
    1.2 worker thread by mal dostatocne casto kontrolovat premennu ukoncenia procesu
    
    2. worker thread moze cakat aj na mutex bez conditional variable alebo semafora
    2.1 main thread nema ako signalizovat opustenie mutexu, musi len pouzit timeout
    2.2 main thread musi cakat, kym ziaden worker thread opusti sekciu ochranenu mutexom, na ktoru worker thready cakali
    2.3 na zrychlenie opustenia kritickej sekcie v bode 2.2 je dobre tiez na jej zaciatku kontrolovat "end_process" premennu (priklad: 100 threadov pristupuje ku kritickej sekcii, ktora trva 10ms => celkovo by main thread musel cakat viac ako 1s)
    26.9.2019 17:04 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Asi už úplně nerozumím, co řešíš? Obecně stačí jedna condition variable pro signalizaci všem workerům (je možné jich mít i více, pokud chceš).

    Pokud ti nějaký worker dlouho čeká na mutex, tak je to špatný design. Mutexy by se měly držet co nejkratší dobu, nemá smysl zamknout mutex a dělat třeba nějakou dlohotrvající síťovou operaci, protože tím zablokuješ všechny ostatní workery, kteří nemůžou nic dělat. Toho je prostě potřeba se vyvarovat.

    Když ti žádný worker dlouho na mutexu nečeká, tak je schopný se rychle sám ukončit. V čem je tedy problém?
    26.9.2019 18:20 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    "Obecně stačí jedna condition variable pro signalizaci všem workerům (je možné jich mít i více, pokud chceš)."

    To nie je pravda. Povedzme, ze mas aplikaciu producer - consumer (2 vlakna) + 1 admin vlakno. Consumer caka na producera s conditional variable "data available". Takisto producer caka na consumera s conditional variable "free slot for data".

    A teraz admin thread ich chce ukoncit. Spravi to len tak, ze:

    1. nastavi premennu "end of process" a bude signalizovat "data available" a "free slot for data"

    2. worker threads po prebudeni z cakania na event si skontroluju "end of process" premennu

    Sledujes, ze admin thread musi signalizovat "data available" a "free slot for data"? Je to jedna condition variable alebo dve? A co ak vlakna pouzivaju 5 conditional variables?

    Teraz k design patternu. Preto sa to vola design pattern, lebo signalizujeme zdanlivo nesuvisiace eventy. Dava ti totiz zmysel, ze pri ukonceni procesu su "data available"? Nie su. Ono by to chcelo signalizovat len "process end", ale to nemozme, lebo vlakno moze cakat na uplne iny event a signalizacia nasho "end of process" nic nevyriesi.

    Admin thread ma mat kontajner vsetkych eventov a signalizovat ich bez ohladu na to, ci nastali. Zaroven worker thready musia checkovat "end of process" podmienku. To je skratka design pattern.
    27.9.2019 02:41 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Viděl jsi ten elementární příklad, který jsem poslal? Je tam jedna condition variable, která signalizuje dva různé eventy: do_work a terminate. Tahle jedna stejná condition variable může být použita pro všechny workery, protože máš na condition variable metodu notify_one (což se hodí pro do_work event, chceš probudit jen jednoho workera, který má něco dělat) a taky metodu notify_all (což se hodí pro terminate_event, chceš probudit všechny workery, aby se ukončily). Takže jedna condition variable stačí pro všechny eventy a všechny workery (někdy může být účelné mít jich více, ale v principu to není nutné).
    27.9.2019 11:45 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Asi si nerozumieme. Ano, jedna premenna staci. To je vsak jedna cast pravdy. Uplna pravda je, ze nielen ze 1 premenna staci, ale viac premennych sa pouzivat v tomto patterne NEMA. Ked chcem pouzit na ukoncenie procesu tuto jednu premennu a chcem mat cakanie vlakien pod kontrolou, NESMIEM pouzit ine premenne. Rozumieme si, ze sa tieto 2 podmienky navzajom vylucuju?

    A rozumieme si aj v tom, ze toto moze zmenit celkom aj design uz napisanej aplikacie, ktora pouziva viacero premennych?
    27.9.2019 11:57 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Nerozumíme si. Jedna conditional variable stačí, ale klidně jich můžeš použít víc, nic se navzájem nevylučuje. Prostě místo jedné conditional variable jich budeš notifikovat víc. Nehledej v tom žádné složitosti.
    27.9.2019 12:23 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    A o tom predsa hovorim! Zlozitost v tom je taka, ze technicky to pre conditional variables funguje, ale nezapada to celkom do loose coupling konceptu. Admin thread totiz nepotrebuje k sebe tahat ziadne dalsie headre, kde su deklarovane dalsie conditional variables.

    Admin thread potrebuje, naopak, vytvorit interface, kde si akykolvek komponent zaregistruje svoj (unnamed) conditional variable, aby bol notifikovany pri ukonceni procesu od admin threadu.

    Naviac, cely tento koncept funguje len pre conditional variables, nevyriesili sme ukoncenie cakania na mutex / semafor... Toto sa ani riesit neda, aj ked ja by som bol rad, keby som videl nieco take ako:
    status = mutex_lock(...);
    if (MUTEX_ABANDONED == status) {
        /* do cleanup here and terminate the current thread */
    }
    4.10.2019 19:15 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Teraz ku condition variable. Neviem, ako si to myslel, ale cakanie na condition variable vyzaduje cakanie na event. Na jeden event. Inak povedane, ak cakam na condition variable "data ready", nemozem cakat na condition "end of process".
    Co ty tvoje worker thready dělají? Pokud čekají někde na nějaké síťové I/O, tak by možná byl dobrý nápad použít epoll(), protože pak můžeš do jednoho epoll-based event loopu naházet nějaké sockety atd. a zároven eventfd deskriptory pro signalizaci nějakých vlastních stavů, jako třeba ukončení apod. epoll pak čeká paralelně na všechny změny stavů, které chceš sledovat. (Také mu můžeš nastavit timeout, pokud to budeš potřebovat.) Nebudeš se pak muset babrat s condition variables apod.
    4.10.2019 19:16 kralyk z abclinuxu | skóre: 29 | blog:
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Případně můžeš použít abstrakci libevent.
    26.9.2019 13:10 luky
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Volatile v souvislosti s mutithreadingem je vždy chyba, nepoužívej volalile pro synchronizaci, nefunguje to. Volatile se prakticky používá pouze k přímému přístupu k hardware (HW registry mapované do paměti).
    Uz jste videl nejaky kod pouzivajici RCU, pripadne knihovnu liburcu?
    26.9.2019 13:29 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Jo viděl, konkrétně v librcu žádná volatile proměnná pro sychronizaci použitá není, jsou tam normálně memory bariéry. Jediné, co se tam používá, je __asm__ __volatile__, což překladači říká, aby ten assemblerový kód nechal, jak je. S volatile proměnnou to nemá nic společného.

    Pokud si myslíš, že používat volatile pro multithreading je dobrý nápad, tak si to myslíš úplně blbě.
    26.9.2019 13:57 luky
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Podivej se znova napriklad na definici CMM_ACCESS_ONCE, _CMM_LOAD_SHARED a _CMM_STORE_SHARED. Pripadne na ekvivalenty z kernelu rcu_dereference_raw a rcu_assign_pointer.
    26.9.2019 14:09 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    A četl jsi komentář k tomu? Pro synchronizaci mezi thready je to úplně k ničemu.

    This macro does absolutely -nothing- to prevent the CPU from reordering, merging, or refetching absolutely anything at any time. Its main intended use is to mediate communication between process-level code and irq/NMI handlers, all running on the same CPU.

    26.9.2019 14:35 luky
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Pri cteni je treba i trochu premyslet, knihovna urcu je "port" rcu z kernelu do user space. Komentar, ktery jste cetl neni relevantni, protoze je to puvodni komentar k makru ACCESS_ONCE. Je to zrejme uz treba jen z toho, ze resi NMI, s kterymy aplikace v uzivatelskem prostoru bude asi tezko pracovat.

    Zkuste si jako priklad napsat trivialni RCU algoritmus pro pridani prvku do spojoveho seznamu a zamyslete se, jestli tam je volatile potreba a nebo ne.
    26.9.2019 15:00 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Ano, je třeba přemýšlet, bohužel jsi to neudělal.

    Co platí pro kernel space, to platí tuplem i pro user space. Volatile samo o sobě nelze použít pro sychronizaci mezi thready, protože volatile říká pouze to, že se hodnota načte z paměti. Jenomže paměť, to může být i cache. A více jader znamená více různých cache, takže ta proměnná může existovat ve více kopiích v různých cache. x86 zajišťuje cache coherency na úrovni hardware, ale jsou architekury (např. některé verze ARMu), kde to neplatí a kde musí být pro koherentní cache zajištěná i nějaká sofwarová podpora (obvykle se to řeší jako cache flush). Tady s volatile tvrdě narazíš.

    Takže znovu opakuji, volatile pro sychronizaci mezi thready nelze použít, vždy tam musí být ještě nějaký jiný mechanismus.
    26.9.2019 15:49 luky
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Volatile samo o sobě nelze použít pro sychronizaci mezi thready
    Jeste pred chvili jsi psal neco jineho:
    Volatile v souvislosti s mutithreadingem je vždy chyba
    26.9.2019 16:03 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Jestli chceš slovíčkařit, klidně můžeš, ale mě to nebaví. V normálním user space kódu nemá volatile v souvislosti s multithreadingem co dělat, pokud to někdo používá, tak je to prakticky jistě špatně. To byl taky případ původního tazatele. Nebaví mě to pořád dokola opakovat, tak si to přečti znovu třeba tady: https://stackoverflow.com/a/45663377
    26.9.2019 16:23 luky
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Vzdyt i v tom odkazovanem clanku se pise, ze volatile se normalne pouziva v lock-free kodu, coz je i pripad meho prikladu s RCU. Prijde mi, ze jsi myslenim zamrzl nekdy na konci 90-tych let, kdy vrchol multithredoveho programovani byla synchronizace pres mutexy, ktera prijatelne skalovala az na 4 CPU. To, ze ti utekl nastup lockfree algoritmu neni duvod, abys nekomu tvrdil, ze pouziti volatile je vzdycky spatne.
    26.9.2019 16:36 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Bohužel jsi nic nepochopil. Volatile samo o sobě v lock-free kódu normálně použít NEMŮŽEŠ. Aby ti volatile v lock-free kódu samo o sobě fungovalo, musí být splněny nějaké kontrétní předpoklady, které obecně neplatí. Pokud píšeš lock-free kód pro x86, tak ti volatile samo o sobě fungovat může, protože cache coherency zajišťuje hardware. Ale to je konkrétní specialita té platformy, stejný kód na ARMu už fungovat nebude. Už chápeš?
    27.9.2019 16:09 luky
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Ujasneme si fakta - ja nikdy netvrdil, ze neni nutne pouzivat bariery. Pri navrhu algoritmu je samozrejme nutne oznacit v kodu mista, kde je bariera potreba a pak podle pouzite platformy dodat pripadny kod. To ty jsi tvrdil, ze pouziti volatile je ve vicevlaknove aplikaci vzdycky spatne a ted tvrdis, ze volatile nemuzes pouzit samo o sobe. Ani to neni pravda, volatile samo o sobe pouzit samozrejme muzes a casto se to deje napriklad pri cteni hodnoty, u ktere mi nevadi, ze nektera vlakna uvidi starou hodnotu a jina novou. Realny priklad (z meho zivota) je pri smerovani zprav, kdy z tabulky ctu index smerovaciho zaznamu a je mi jedno, jestli si prectu index stary a nebo novy, ale potrebuju zajistit, ze se prekladac nerozhodne behem zpracovani zpravy precist index zaznamu znovu, coz by bez pouziti volatile mohl klidne udelat.
    27.9.2019 16:24 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Zase slovíčkaříš. Od začátku jsme se bavili o user space kódu, který má běžet pokud možno všude bez ohledu na použitý hardware. Ty jsi do toho začal míchat low level sychronizační primitiva (ano lock-free struktury jsou low level sychronizační primitiva), která se naopak píšou na konkrétní hardware s nějakými předpoklady o chování toho železa pod tím kvůli maximálnímu výkonu. Takový kód poběží jen na hardware, pro který byl napsán, není portabilní. Low level sychronizační primitiva normálně nikdo nepíše a nebavili jsme se o nich.

    A ten tvůj příklad s volatile "čtu index směrovacího záznamu" nedává žádný smysl, tohle máš prostě blbě. Když je ti jedno, jestli přečteš starý nebo nový index, proč ho vůbec čteš? Můžeš použít starou hodnotu, nemusíš nic číst z paměti. Pokud předpokládáš, že tu novou hodnotu uvidíš někdy v budoucnu, tak to předpokládáš blbě, protože jsou platformy, kde není zaručeno (bez další sychronizace), že tu novou hodnotu vůbec někdy uvidíš, nemusí se to vůbec stát a budeš pořád i s volatile číst starou.
    27.9.2019 19:04 luky
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Pres ten muj priklad aktualne tece ~40% celosvetoveho control plane v mobilnich sitich.
    27.9.2019 19:51 linuxák
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    A? To neznamená, že to nemáš blbě. Může ti to fungovat, protože hardware pod tím splňuje nějaké předpoklady (třeba koherenci cache). Ale je potřeba říct, že obecné řešení to není a na jiném hardware to fungovat nebude. To by sis měl ujasnit, až budeš zase někam cpát volatile pro multithreading, opravdu to není dobrý nápad.
    26.9.2019 17:02 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Volatile premenna zial zarucuje len to, ze sa instrukcia zapisu v danom vlakne vykona a nebude optimalizovana. Nezabezpeci ti memory barieru, cize:

    1. memory ordering na danej pozicii instrukcie

    2. cache koherenciu medzi jadrami, cize propagaciu hodnoty k druhemu jadru
    25.9.2019 22:58 Miloslav Ponkrác
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    To velice záleží od architektury aplikace. Většinou už sama architektura multithreadové aplikace sama vede k tomu, jak v daném případě postupovat.

    Mimochodem, někdy je v pořádku některá vlákna ukončit přirozeně, některá zabít. Následně uvolnit synchronizační objekty, pokud to neudělá (většinou udělá) operační systém sám. A ukončit proces.
    26.9.2019 00:09 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    "Většinou už sama architektura multithreadové aplikace sama vede k tomu, jak v daném případě postupovat."

    Lenze ako som spominal, so sucasnymi mutexami a synchronizacnymi primitivami to nie je mozne. Povedzme, ze worker thread caka na mutex. Ako ho chces prebudit a povedat mu "koncime!". To nie je mozne so sucasnymi synchronizacnymi primitivami.

    26.9.2019 13:12 luky
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Cti manual - PTHREAD_MUTEXATTR_SETROBUST
    29.9.2019 11:29 M. Ponkrác | skóre: 3
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Jinak řečeno, musíte navrhnout multithreadovou aplikaci tak, aby ji bylo možné rozumně rychle ukončit. Musíte na to myslet už při návrhu.

    Pak je to také otázka platformy.

    Například u pthread je návrh takového programu řádově těžší, protože má relativně málo možností práce s thready i synchronizačními primitivy.

    V případě Windows API jsou možnosti větší, a lze snadno a korektně ukončit i thready v různých nešikovných situacích, kde by to v pthread vůbec nebylo možné.
    2.10.2019 11:31 majvan | skóre: 5 | blog: Fandime linuxu | Trenčín
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Jasne, ale ja som rozmyslal skor o multiplatformnom rieseni, aj ked rozumiem, ze nie vzdy vsetko sa da generalizovat. Preto som skusil predostriet otazku, ci existuje nejaky design pattern, ktory sa dodrzuje.
    4.10.2019 19:02 kvr
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    Doporučuju se podívat na ExecutorService v Java. V zásadě je rozdělený na thread management a (nejlépe malé) user tasky, které provedou jasně daný úkol a skončí. Thread management si pak kontroluje přes eventy, zda je čas skončit. Technicky vzato, podporuje i interrupt, ale ten se obecně nedoporučuje, neboť asynchronní interrupt může napáchat dost škody, zvlášť, pokud jsou nějaké otevřené mutexy, semafory, conditions apod. Pokud by šlo o nějaký dlouhý "busy" task, tak sdílená proměnná může pomoct taky, u IO naopak poslat signal. Jenže pak už se ztrácí kouzlo rozdělení, kde za thread management je odpovědný ExecutorService a tasky jenom řeší malou úlohu. V Java to v zásadě funguje ještě dobře, neboť má (relativně) konsistentní návrh, jak se interrupted signal doručuje threadům, v C/C++ se to bude řešit hůř, neboť každý framework má jiný přístup (v zásadě jediná garance je návratová hodnota EINTR, atomický suspend signálu + pselect/ppoll/epoll, ale pořád je třeba nainstalovat správný signal handler atd).

    Jinak k té volatile sdílené (nemusí být globální, to je prasárna) proměnné jako indikátoru ukončení - pominu-li jiné aspekty (zaseknutí na IO nebo sleep), tak ten volatile v zásadě fungovat bude, pokud její obsah bude v nějaké době doručen. Což dříve udělá jakákoliv architektura, v nejhorším případě poté, co bude vlákno přerušeno OS a systém invokuje memory barrieru. Volatile kompilátoru říká, že nesmí optimalizovat přístup paměti, takže i když nebude fungovat memory ordering, tak ta proměnná se tam časem zpropaguje a kód si ji přečte.

    Není to ale bezpečné z důvodů výše - například thread čekající na další task z event queue, čekající na IO, si tu proměnnou nepřečte. Řešením je tedy poslat thread exit event skrz stejnou frontu, kterou posílá tasky, pro IO mít nějakou high-level konsistentní abstrakci nad tím, jak thready zpracovávají system signaly.
    10.10.2019 15:10 Lyco | skóre: 14 | blog: Lyco
    Rozbalit Rozbalit vše Re: Spravne ukoncenie multithread aplikacie - architektura
    K tomuhle slouží Thread Cancellation. Kvalita implementací se ale liší :( Viz Thread cancellation and resource leaks na EWONTFIX
    Příspěvek se rázem stává až o 37,5 % pravdivější, je-li pod ním napsáno reálné jméno.

    Založit nové vláknoNahoru

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.