Open source platforma Home Assistant (Demo, GitHub, Wikipedie) pro monitorování a řízení inteligentní domácnosti byla vydána ve verzi 2024.12.
Byla vydána verze 31.0 svobodného softwaru OBS Studio (Open Broadcaster Software, Wikipedie) určeného pro streamování a nahrávání obrazovky počítače. Přehled novinek na GitHubu. Instalovat lze také z Flathubu.
Emulátory Box86 a Box64 umožňující spouštět linuxové aplikace pro x86 a x86_64 na jiných než x86 a x86_64 architekturách, například ARM a ARM64, byly vydány v nových verzích: Box86 0.3.8 a Box64 0.3.2. Ukázka možností na YouTube.
Byla vydána nová verze 6.1 neměnné (immutable) distribuce openSUSE Leap Micro určené pro běh kontejneru a virtuálních strojů. S vydáním verze 6.1 byla ukončena podpora verze 5.5.
Poslanci dnes ve třetím čtení schválili návrh zákona o digitálních financích. Cílem zákona je implementace předpisů Evropské unie v oblasti digitálních financí, konkrétně nařízení DORA (Digital Operational Resilience Act) o digitální provozní odolnosti finančního sektoru a nařízení MiCA (Markets in Crypto Assets) o trzích kryptoaktiv. Zákon nyní míří k projednání do Senátu ČR. U kryptoměn bude příjem do 100 tisíc Kč za zdaňovací období osvobozen od daně, podobně jako u cenných papírů, a to za podmínky jejich držení po dobu alespoň 3 let.
O víkendu (15:00 až 23:00) proběhne EmacsConf 2024, tj. online konference vývojářů a uživatelů editoru GNU Emacs. Sledovat ji bude možné na stránkách konference. Záznamy budou k dispozici přímo z programu.
Mozilla má nové logo a vizuální identitu. Profesionální. Vytvořeno u Jones Knowles Ritchie (JKR). Na dalších 25 let.
Bylo rozhodnuto, že nejnovější Linux 6.12 je jádrem s prodlouženou upstream podporou (LTS). Ta je aktuálně plánována do prosince 2026. LTS jader je aktuálně šest: 5.4, 5.10, 5.15, 6.1, 6.6 a 6.12.
Byla vydána nová stabilní verze 3.21.0, tj. první z nové řady 3.21, minimalistické linuxové distribuce zaměřené na bezpečnost Alpine Linux (Wikipedie) postavené na standardní knihovně jazyka C musl libc a BusyBoxu. Z novinek lze vypíchnou počáteční podporu architektury Loongson LoongArch64.
Ahoj,
chtel bych se zeptat, jakou technikou se delaji programy, aby nemusely mit nekonecnou smycku while (1) { ... }, ktera zbytecne zatezuje procesor.
Program by mel byt ciste konzolovy, takze pouziti Qt, GTK knihoven neni mozne.
Od programu se ocekava soubezne obsluhovani vice seriovych portu, provadeni periodickych cinnosti (napr odeslani dat po seriovem portu)
a zaroven refresh UI na zaklade urcitych udalosti (prijata data ze SP, periodicke cinnosti atd...).
Vyhovovalo by mi neco jako udalostmi rizene programovani. Ale bohuzel jsem nikde nenasel jak na to.
Diky vsem za help.
Tomas
Smyčka je základem mnoha programů Na události se čeká, nejlépe pasivně. Buď použitím blokujících IO operací, nebo použitím selectu/epollu. Záleží na tom, s čím budeš pracovat, kernel určitě pro to nějakou podporu mít bude. Může být těžké více věcí ohlídat v jednom vlákně, dá se proto použít více vláken nebo procesů a mezivláknová, resp. meziprocesová (neboli IPC) komunikace a synchronizace.
Takže to UI máš v textové konzoli? Já bych takový program navrhl asi za použití klient-server architektury, server by dělal všechnu tu práci a klienti by byly právě ty UI programy, které by jen hezky zobrazovaly data ze serveru. Takhle se dělá kde co, včetně hudebních přehrávačů. Samozřejmě tam dole pokaždé nějaká smyčka bude, co myslíš, že je v GTK nebo Qt?
BTW. předpokládám, že tohle má být pokračování této diskuze Možná by bylo lepší, kdyby ses více rozepsal o svém projektu, pokud je přínosný a open-source, asi by podle mě bylo vhodnější začít (třeba zde) nějakou spolupráci s někým, kdo je ti ochoten pomoc, protože opakováním v podstatě stejného dotazu se nedozvíš o mnoho víc než minule.
Smyčka je základem mnoha programů Na události se čeká, nejlépe pasivně. Buď použitím blokujících IO operací, nebo použitím selectu/epollu. Záleží na tom, s čím budeš pracovat, kernel určitě pro to nějakou podporu mít bude. Může být těžké více věcí ohlídat v jednom vlákně, dá se proto použít více vláken nebo procesů a mezivláknová, resp. meziprocesová (neboli IPC) komunikace a synchronizace.
No v podstate jde o jednosmernou komunikaci od /dev/js0, pak obousmerna komunikace od /dev/ttySx, a ziskani obrazu z kamery, pripadne vstup od uzivatele, (pauza, stop, play). Program v podstate dostane waypointy, po spusteni si ziska informaci z GPS (po seriove lince), pak ze senzoru (po seriove lince) a obraz z kamery. Nasledne tyto data zpracovava (obraz z kamery ve vlastnim vlakne). Behem zpracovani musi byt schopen reagovat na prijate data ze seriovych linek (napr zda ultrazvuky nenasly prekazku) a pak musi periodicky odesilat data na seriovy port. Po zpracovani je vyhodnocen novy prikaz pro pohonou jednotku a cyklus jede znovu. V podstate jenom mi jde o to, abych odstranil 100 zatez CPU, ktera je zpusobena touto smyckou. Zavolat v teto smycce fci sleep s nejakym kratkym intervalem sice vede ke snizeni zateze, ale stejne to neni to, co bych potreboval.
Takže to UI máš v textové konzoli? Já bych takový program navrhl asi za použití klient-server architektury, server by dělal všechnu tu práci a klienti by byly právě ty UI programy, které by jen hezky zobrazovaly data ze serveru. Takhle se dělá kde co, včetně hudebních přehrávačů.
Soucasne to je reseno tak, ze program je pusten po ssh. Neni potreba obsluhovat vice klientu (viz ucel programu napsany dole).
Samozřejmě tam dole pokaždé nějaká smyčka bude, co myslíš, že je v GTK nebo Qt?
No mozna je, ale "nezere" 100 vykon CPU...
BTW. předpokládám, že tohle má být pokračování této diskuze Možná by bylo lepší, kdyby ses více rozepsal o svém projektu, pokud je přínosný a open-source, asi by podle mě bylo vhodnější začít (třeba zde) nějakou spolupráci s někým, kdo je ti ochoten pomoc, protože opakováním v podstatě stejného dotazu se nedozvíš o mnoho víc než minule.
No toto delam jako bakalarskou praci, takze musim sam :) Jde o robota, ktery se ma autonome pohybovat v prostredi. Uvnitr je obycejny PC (s 35W TDP procesorem AMD). Vsechny ridici algoritmy uz mam napsane, ale nelibi se mi ta hlavni smycka. Jelikoz robot je napajen z baterii, mame nastavene CPU frequency scalling, ale pri pusteni toho programu se vykon CPU timto zvysi a zkrati se tak maximalni doba vydrze baterii. Proto bych to chtel nejak odstranit. Nove vlakno jsem vytvoril z duvodu, ze to predchozi bylo mireno na seriovy port, zde jsem se ptal obecne, na techniku programovani tohoto druhu aplikaci.
Snad uz je ted jasnejsi co vlastne potrebuji. Dekuji Tomas
Pak patrne zalezi na tom, jak casto je treba celou smycku provadet. No a vzdycky na zacatku zmerit aktualni cas, a na konci pockat dokud neuplyne doba, na kterou je nastavena perioda smycky. Pokud byste ovsem chtel jeste zachytit nejake udalosti v prubehu toho cekani, musel byste napriklad cekat na nejaky jiny thread, ktery by cekal na prislusnem zarizeni a informoval by vas jen v pripade, ze by se tam objevila nova data.
Praveze potrebuji zachycovat udalosti, ktere chodi "nahodne". No to jedno cekaci vlakno by mozna bylo reseni. Ale jakym zpusobem lze informovat to hlavni vlakno, ze se ma rozjet? A jak vubec to hlavni vlakno zastavit?Pak patrne zalezi na tom, jak casto je treba celou smycku provadet. No a vzdycky na zacatku zmerit aktualni cas, a na konci pockat dokud neuplyne doba, na kterou je nastavena perioda smycky. Pokud byste ovsem chtel jeste zachytit nejake udalosti v prubehu toho cekani, musel byste napriklad cekat na nejaky jiny thread, ktery by cekal na prislusnem zarizeni a informoval by vas jen v pripade, ze by se tam objevila nova data.
select()
těžko zařídíte.
Ano prave toto potrebuji. Napriklad kdyz budou probihat algoritmy pro zpracovani obrazu (ktere urcite nedokazu naimplementovat super rychle) a prijde po seriove lince, ze ultrazvuk zachytil prekazku. Tak v momente kdy by si ji ridici program teprv vyzvedl uz by mohlo byt pozde :)
Tomas
Rozhodne napis zpracovani jednotlivych kanalu (ser. portu, kamery apod.) do zvlast vlaken (nebo idealne programu, ktere se ti pak budou i lip ladit). Otazkou pak zustava, jak napsat hlavni ridici program. V zasade mas tyhle moznosti jak zasilat a zpracovavat informace z podrizenych programu:
- pres file-descriptory - pak jednoducha smycka se select (vis, ze select muzes provest na vice FD najednou?)
- pres klasicke POSIX signaly (neni moc elegantni)
- pres sockety (klidne i pres TCP a 127.0.0.1) - dobre se ladi a simuluje a v budoucnu skaluje
- pouzij Qt - tohle bych zvolil ja, protoze jejich signal/slots funguje hezky a Qt obecne ti uspori spoustu prace
Jo - jeste pro uplnost - vynechal jsem jeste pouziti shared memory a pouziti nejake MPI knihovny, protoze si myslim, ze to je pro tebe over-kill.
select()
, poll()
a další vlastně vytvořeny: buď se budete dívat moc často a zbytečně zatěžovat procesor, nebo ne dost často a budete mít dlouhou odezvu.
Vy jste navrhoval nulový timeout, takže pak se vám select()
hned vrátí a jen řekne, jestli máte data nebo ne. Jenže pokud něco potřebujete aktivně provádět, pak to musíte proložit opakovanými voláními toho select()
. To má ale dva problémy: za prvé to nemusí být úplně jednoduché. Za druhé buď budete select(..., 0)
volat hodně často a zbytečně tím zatěžovat procesor, nebo méně často a pak se o datech dozvíte až s určitým zpožděním. Což je přesně problém, kvůli kterému select()
vůbec vznikl - abyste při čekání na víc deskriptorů nemusel ve smyčce volat neblokující čtení.
Tato situace, kdy potřebujete čekat na deskriptor a zároveň provádět něco, co vám select()
nepokryje (tj. něco, co není čekáním na deskriptor nebo signál), je prostě případem, kdy je daleko jednodušší a efektivnější oddělit ty dvě věci do samostatných threadů nebo procesů.
Ta konstrukce z prvního odstavce sice zní rozumně, ale je to řešení pro úplně jinou situaci, než jakou řeší tazatel.
Takze som neusetril nic a prepinanie vlaken tiez nieco stoji. A snazim sa ako mozem, ale spozdenie dat nedokazem najst. Kde by malo byt?
Pokud budete select(..., 0)
volat s periodou t, pak přijdou-li data, zpracujete v průměru se zpožděním t/2 (ale při troše smůly to může být skoro t). Zvolíte-li t nízké, budete zbytečně zatěžovat procesor neustálým voláním syscallu select()
, zvolíte-li ho vysoké, pak bude úměrně tomu vysoká i odezva. Pokud použijete nenulový timeout, pak během čekání nemůžete dělat nic jiného.
Tak si přečtěte ty ostatní příspěvky. Tazatel potřebuje provádět časově náročné algoritmy pro analýzu obrazu a během jejich zpracování mohou přijít nějaká data na sériový port; pokud k tomu dojde, potřebuje je zpracovat pokud možno okamžitě. Ano, není to úplně typická situace, ale on právě takovou situaci má a právě takovou situaci potřebuje řešit.
Co se časové náročnosti týká, když jsem to kdysi měřil (nějaký Athlon64 kolem 2 GHz), časová náročnost páru lock+unlock byla podle typu mutexu 27-30 nanosekund. Sice jsem nezkoušel měřit select()
, ale už s ohledem na to, že je to syscall, zdá se mi nepravděpodobné, že by jeho náročnost mohla být na stejné úrovni. Ale jestli chcete, klidně to zkusím.
Uvnitr je obycejny PC (s 35W TDP procesorem AMD). Vsechny ridici algoritmy uz mam napsane, ale nelibi se mi ta hlavni smycka. Jelikoz robot je napajen z baterii, mame nastavene CPU frequency scalling, ale pri pusteni toho programu se vykon CPU timto zvysi a zkrati se tak maximalni doba vydrze baterii.
Je nutne pouzit bezny PC? Neslo by treba pouzit alix3d3 nebo BR-6104KP?
Smyčka je základem mnoha programů Na události se čeká, nejlépe pasivně. Buď použitím blokujících IO operací, nebo použitím selectu/epollu. Záleží na tom, s čím budeš pracovat, kernel určitě pro to nějakou podporu mít bude. Může být těžké více věcí ohlídat v jednom vlákně, dá se proto použít více vláken nebo procesů a mezivláknová, resp. meziprocesová (neboli IPC) komunikace a synchronizace.
Takže to UI máš v textové konzoli? Já bych takový program navrhl asi za použití klient-server architektury, server by dělal všechnu tu práci a klienti by byly právě ty UI programy, které by jen hezky zobrazovaly data ze serveru. Takhle se dělá kde co, včetně hudebních přehrávačů. Samozřejmě tam dole pokaždé nějaká smyčka bude, co myslíš, že je v GTK nebo Qt?
BTW. předpokládám, že tohle má být pokračování této diskuze Možná by bylo lepší, kdyby ses více rozepsal o svém projektu, pokud je přínosný a open-source, asi by podle mě bylo vhodnější začít (třeba zde) nějakou spolupráci s někým, kdo je ti ochoten pomoc, protože opakováním v podstatě stejného dotazu se nedozvíš o mnoho víc než minule.
Jeste jsem uvazoval o tom pouziti modelu klient/server. Mozna by to bylo vyhodne uz jen proto, ze by bylo mozne ovladat aplikaci i vzdalene a moznost udelat i nejake GUI, misto textoveho UI v konzoli.
Rikal jsem si, ze by byl nejaky daemon, ktery by naslouchal na urcitem portu. A mel by nastarost komunikaci s hardwarem (seriove porty, joystick, kamera). Zde by byla funkce select pro obsluhu jednotlivych zarizeni. K tomuto serveru by se pak pripojila hlavni aplikace, ve ktere by byly naimplementovany ridici algoritmy ktere by pak komunikovaly s hardwarem prostrednictvim socketu. Cili hlavni aplikace by pak mohla behem cekani na urcita data provadet i neco jineho.
Byl by tento model uz lepsim resenim, nebo je zde nejaky schovany "problem".
Mnohokrat dekuji za cenne rady!
man select man select_tutterminal je deskriptor, sietove sockety tiez, ak pristupujes k ser. portu cez zariadenie z dev, tak tiez. Takze nic nestoji v ceste pouzit select. V najhorsom pripade s nejakym timeoutom, ale ak sa da, tak je lepsie bez neho.
ano to mi je jasne, ale jak jsem psal: nemuzu cekat na nejakou udalost, protoze potrebuji behem toho provadet jinou cinnost.
Takze spis by se mi hodilo neco na zpusob udalostmi rizene programovani.
Proste prijdou data na port, vygeneruje se udalost, kterou vyridim, uzivatel pohne joystickem, vygeneruje se udalost na kterou patricne zareaguji. Vyprsi casovac, provede se nejaka akce.
Kameru jsem si uz udelal ve vlastnim vlakne, takze tu neni potreba resit.
Napriklad zkousel jsem si udelat tridu pro praci se seriovym portem, ktera vytvori dve dalsi vlakna a otevre port v blokujicim rezimu. Jedno vlakno bude tedy stat na fci read na seriovy port, v pripade prijatych dat vlakno tedy pokracuje v behu, kde ulozi data do bufferu a pusti funkci, kterou uzivatel dane tridy nastavil pomoci ukazatele na ni. U odesilaciho vlakna jsem nevedel, jak predat data k odeslani. Respektive nevedel jsem jak "zastavit" odesilaci vlakno, aby cekalo az nekam poslu data. Zatim jsem to vyresil tak, ze odesilaci vlakno se vytvori v pripade ze chce uzivatel neco odeslat a hned potom skonci. Coz me prijde neefektivni.
Tomas
No pak se musi pouzit mezivlaknova komunikace, napr. pomoci zamku a cekani na ne. Prislusne funkce jsou bud z rodiny pthread_cond* nebo pthread_mutex* (presne to nevim, a nemam tu nainstalovane jejich manpages).
Takze spis by se mi hodilo neco na zpusob udalostmi rizene programovani.Už jsem ti to doporučoval minule - zkus si najít něco o signálech a jejich použití. Jestliže potřebuješ událostmi řízené programování, nedovedu si představit vhodnější řešení. (Vlákna nebo dokonce IPC jsou v tomto případě neskutečný overkill.)
Ano, ale signaly pro uzivatelske pouziti jsou definovane jen dva SIGUSR1 a SIGUSR2. To me nestaci...
man kill
, v htop
u. Ty, jak už název napovídá, signalizují, že se něco stalo.
Například si vezměme SIGTERM - tenhle signál se pošle programu, když mu dáš Ctrl-C, když se vypíná počítač (zařizuje nějaký skript, pošle SIGTERM všem) apod. Program má automaticky v sobě zabudovanou nějakou obsluhu tohoto signálu (většinou takovou, která program ukončí), ale ty ji můžeš předefinovat, například ji nechat vypsat "teď se nemůžu ukončit" a nechat program běžet dál. man sigaction
Pak tu máme signál SIGIO, který tě asi bude zajímat víc. Ten se procesu man sigaction
)Proste prijdou data na port, vygeneruje se udalost, kterou vyridim, uzivatel pohne joystickem, vygeneruje se udalost na kterou patricne zareaguji. Vyprsi casovac, provede se nejaka akce.Výše uvedené v tomhle případě stačit nebude (možná by to šlo, ale je to pěkný hnus), proto je tu druhá varianta. Na funkce jednotlivě obsluhující signály se vykašleme (zapomeň na
sigaction
, místo toho se zablokují všechny signály, na které chceš reagovat (man sigemptyset
, man sigaddset
, man sigprocmask
), nastavíš, co je potřeba nastavit (např. ty fcntl z příkladu výše) a vstoupíš do nekonečné smyčky:
(Příklad - program může přijmout data z portu, každou vteřinu vyprší časovač, pomocí Ctrl-C se to celé ukončí.)
for (;;) { rv = sigwaitinfo (&signaly_waitset, &signal_info); if (rv < 0) { ... } switch (signal_info.si_signo) { case SIGALRM: { printf ("Uplynula jedna vteřina, spácháme periodickou činnost\n"); ... break; } case SIGTERM: { printf ("Program končí\n"); ... exit(0) } case SIGIO: { printf ("Přišla nám od někoho nějaká data, zjistíme, kdo to je a co chce\n"); ... break; } default: { printf ("Přišel signál, který jsme si neobjednali, vynadáme číšníkovi\n"); break; } } }Tohle už je lepší a dělá to víceméně to, co potřebuješ. V té smyčce mohou být další věci, ale pozor - program se ve volání
sigwaitinfo
zastaví a bude čekat tak dlouho, dokud nepřijde nějaký signál. (Přesněji - zastaví se vlákno, ve kterém tu funkci voláš, jiná vlákna samozřejmě poběží dál.)
Ještě pořád to má háček, že u obsluhy toho SIGIO budeš muset zjistit, odkud ta data přišla (pokud tedy nebudeš takto asynchronně přijímat jenom z jednoho souboru), což je trochu protivné. Nechá se to obejít tak, že si místo SIGIO necháš posílat nějaký real-time signál a pak ve struktuře signal_info dostaneš informaci o tom, ze kterého fd ten signál přišel.
proto furt trvam na tom ze uloha je resitelna pres select/pollStejně tak je úloha řešitelná přes vlákna. Proč to dělat jednoduše, když to jde složitě, že?
Signaly by z toho asi vypadly uplne.Vypadly by jenom částečně - programátor je nevidí, ale jsou tam furt. Ale dobrá, tohle by možná o tolik složitější nebylo - asi to bude víc o zvyku. Ale ta vlákna?
SIGTERM - tenhle signál se pošle programu, když mu dáš Ctrl-C
Ctrl-C posílá INT
, ne TERM
.
AFAIK cyklus sa da v C++ nahradit pomocou sablon.
Ahoj!
Já teď dělám něco podobného. Sice mám místo sériového portu síť, ale nevadí. Dělám to vlákny. V mém případě je to nejelegantnější řešení. Největší "challenge" je synchronizace těch vláken. Možná ti to pomůže, možná ne.
Aha, takže odpovědí na dotaz je vlastně flame na téma vlákna, ano či ne.
Ne, ne. V pořádku. Rád se sám poučím, jak se to má dělat. Jen jsem chtěl sdělit mé zkušenosti, protože zrovna teď dělám na "něčem podobném". Spíš jsem tím komentářem reagoval na Josefa Kufnera, který do každého vlákna zasel svůj hrob. Má aplikace funguje přes vlákna bez nejmenších potíží. Nesouhlasím tedy s výrokem, že je to cesta do pekel. Vím, že na některé úlohy nejsou vlákna vhodná, ale jsou úlohy, kde se vlákna hodí a vyndají. Zadání úlohy na mě nepůsobí, že by vlákna měla významný vliv na výkon, stabilitu či funkčnost. Toš tak. Uf.
Prostě mi to zadání přišlo strašně podobné tomu, co teď sám řeším. Tak jsem chtěl jen pomoci. :'(
Má aplikace funguje přes vlákna bez nejmenších potíží. Nesouhlasím tedy s výrokem, že je to cesta do pekel.Jasně. Když člověk ví, jak na to, a lepší řešení není, tak proč vlákna nepoužít... Mě šlo spíš o to, že v jazyce, který má možnost využít nativní prostředky systému (předpokládám, že když se tazatel ptá ve vlákně, které začíná C/C++, tak má možnost tyto prostředky využít), jsou vlákna pravděpodobně zbytečná, protože existují efektivnější metody jak dělat věci naráz (přesněji jak čekat na víc věcí naráz) - efektivnější např. v tom, že v podstatě není potřeba řešit synchronizaci mezi vlákny. O cestě do pekel s vlákny se dá mluvit, pokud člověk s programováním začíná a nemá moc zkušenosti s tím, co se děje pod pokličkou; tj. že ho vůbec nenapadne, že to či ono by se mohlo pěkně posesouvat.
Ahoj,
predne bych chtel vsem podekovat za posilani cennych rad a pripominek k teto problematice. Vim ze me to neomlouva, ale chtel bych podotknut, ze nejsem informatik, studuji na elektro fakulte, takze nase kurzy programovani nebyly na takove urovni. Vse se ucim z vlastniho zajmu sam, pripadne se snazim vybirat volitelne predmety ve skole, ktere by me neco mohly dat...
Dnes jsem byl za vedoucim sve prace. Ta metoda server a klient, kterou jsem popsal zde v jednom z prispevku, se mu libila. Ale rekl mi, ze tento styl programovani, kde bezi jedna smycka, se delalo tak v dobach DOSu a ze se mam poohlednout po jinem reseni a vyuzit tak moznosti operacniho systemu - zminil prave ty vlakna. Jeho ostatni roboti na fakulte jsou postaveny na bazi Windows, takze pry moc Linux nezna. Ale i na jednocipech se tzv: force smycka nedela. (napr freescale uz v manualech maji uvedeno, ze takto se to delat nema a jsou tam tusim nejake tasky).
Takze abych splnil predstavy meho vedouciho, mel bych aplikaci navrhnout jako vicevlaknovou. Ovsem nerikam ze pak v tom konkretnim vlakne nepouziji fce select poll nebo epoll.
Jinak me jeste neni jasne, jak bych mohl udelat nasledujici: vlakno A je vytvoreno pri inicializaci programu a jeho ukolem je napriklad na zaklade prijatych dat vypocitat neco a vysledek odeslat na seriovy port. Zde nevim jakym zpusobem predat vlaknu vstupni data a jakym zpusobem toto vlakno zastavit aby na ty vstupni data cekalo...
Dekuji Tomas
Podle toho, jak jste v rychlém sledu napsal na různá místa diskuse tři nebo čtyři příspěvky s prakticky stejným obsahem (v duchu "vlákna jsou špatně") to tak působilo.
Bohužel mám pocit, že řada linuxových programátorů (netvrdím, že je to zrovna váš případ) si za dob LinuxThreads, kdy v Linuxu nebyla vlákna implementována příliš prakticky a efektivně, začala vymýšlet argumenty, že chyba je v koncepci vláken jako takových, takže kvalitní implementace vlastně vůbec nikomu nechybí. Vzpomínám si např. na výrok jednoho (jinak velmi dobrého) programátora: "Vlákna jsou berlička pro ty, kdo neumějí správně používat fork()
." Někteří bohužel ani po příchodu NPTL svůj postoj nepřehodnotili a neakceptovali, že problém byl v té původní implementaci, ne v konceptu samotném.
no nevim totez tvrdi o vlaknech napr ESR.
Promiň, ale vidím to takto: hlavní aplikační vlákno vystaví vlákno s GUI, spustí vlákna obsluhy sériových portů a zamkne se, dokud tato vlákna neskončí. V případě té události, jak píše, že na ni musí reagovat UI, stačí jen sdělit vláknu, které se stará o UI, že má něco nějak překreslit, z vlákna, které obsluhuje ty porty. Vidím v tom jen bariéry a fronty (buffery událostí).
Jak jsem psal — opakuji — píšu teď něco podobného v Javě, akorát že místo UI posílám notifikace zainteresovaným JMX klientům. Mým GUI je například JConsole.
Je to jednoduché, elegantní, přehledné a hlavně — není co ladit. Zvlášť, když použije C++ — je to pár tříd. Já mám ve své proof-of-concept verzi třídy čtyři a není to žádný anti-pattern.
Takže vlákna do hrobu pomůžou tak akorát vývojáři Microsoft Wordu při implementaci kontroly pravopisu, když zrovna probíhá tisk na pozadí.
P.S.: Nemyslím si, že C++ je hloupější než Java. Naopak. Myslím si, že C++ (STL?) je na tyto věci připraven(a?) nejhůře tak, jako Java; spíš lépe. To nechť posoudí někdo, kdo ovládá Javu i C++.
Jakej overkill? To mám jako všechno psát v JNI a hákovat to do native metod? Méně řádků kódu — méně chyb.
A na druhou stranu: když započítám JVM a všechen ten moloch okolo — vystavení nového vlákna operačním systémem je opravdu, z pohledu kódu v Javě, nejrychlejší operace.
Takže suma sumárum — takhle je to nejjednodušší. Krátký, čitelný a rychlý (vzhledem k business požadavkům) kód, který funguje.
A na druhou stranu: když započítám JVM a všechen ten moloch okolo — vystavení nového vlákna operačním systémem je opravdu, z pohledu kódu v Javě, nejrychlejší operace.No jasně, právě na to jsem narážel
Je to jednoduché, elegantní, přehledné a hlavně — není co ladit.Jo, to říkej lidem, kteří si nechají od operačního systému diktovat, že vlákna jsou drahá, a vymýšlejí paralelismus bez paralelismu
Řeknu to asi takto: nevšimnul jsem si, že by vlákna u operačních systémů byla drahá.
Omlouvám se. Špatně jsem se vyjádřil.
Jen doplním: když už jsou vytvořena v poolu.
Takze napriklad pro odeslani dat na seriovy port je jednoduzsi naprogramovat to tak, ze je vytvoreno nove vlakno, odesle ty data a skonci
Nez mit konstantne vytvorene jedno vlakno a slozite pomoci mutexu ho nejak zastavovat? Vykon to nijak neohrozi?
To v podstatě říkáme oba to samé: že je výhodnější mít tam trvale thread, který se bude starat o asynchronní odesílání dat, než vytvářet na každý blok dat nový thread.Neříkáme (ale uznávám, že jsem to nenapsal dost jasně) - já tvrdím, že na odesílání dat po sériovém portu je úplně zbytečné mít samostatný thread. Port lze v případě potřeby otevřít s O_NONBLOCK, takže zápis nebude blokovat.
write()
jako taková by měla být thread-safe (aspoň podle normy)
Jediné, na čem by tenhle postup mohl selhat, je zápis bloku dat většího než je jaderný buffer (u mě 4kB) najednou; to by se muselo provádět na etapy a tam už by možná stálo za to použít vlákno (osobně nicméně považuju tak velký blok dat pro řízení za nepravděpodobný, leda by se příkazy posílaly slovně)
Tak jsem se dokopal udělat ty testy, orientační výsledky pro rámcovou představu:
pthread_mutex_lock()
+ pthread_mutex_unock()
: 26 nswrite()
(1 B): 83 nsselect()
(jeden deskriptor pro čtení, žádná data): 223 nswaitpid()
: 111 μs(Phenom 9750 2.4 GHz, OpenSuSE 11.0 x86_64)
Program by mel byt ciste konzolovy, takze pouziti Qt, GTK knihoven neni mozne.Qt umožňuje napsat čistě konzolový program - knihovna QtCore nezávisí na žádném grafickém prostředí a jde používat i v řádce.
Vyhovovalo by mi neco jako udalostmi rizene programovani. Ale bohuzel jsem nikde nenasel jak na to.Většina objektů umí v reakci na událost (časovač vypršel, přišla data po síti) vysílat signály (jde o něco jiného, než jsou linuxové signály popsané výše; linuxové signály lze nicméně na Qt signály převést), ty si nastavíš, jak na ně chceš reagovat (naprogramováním příslušné obslužné rutiny - nebo rutin - signálu) Spousta věcí, které řešíš (časovače, vlákna) je v knihovně obsažena, takže jde v podstatě jenom o to je napojit. Pokud bys nechtěl koupit licenci, musel bys výsledek vydat pod GPL (což u školní práce nevidím jako problém)
Díval jste se na knihovnu ASIO? Třeba by se vám hodila, jestli to budete dělat v c++. Je také součástí budoucího standardu c++0x.
Tiskni Sdílej: