Diskuze: Vlákna a zámky
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Zobrazeno 11 zpráv z 11.
K personalizaci obsahu a reklam, poskytování funkcí sociálních médií a analýze naší návštěvnosti využíváme soubory cookie. Informace o tom, jak náš web používáte, sdílíme se svými partnery pro sociální média, inzerci a analýzy. Partneři tyto údaje mohou zkombinovat s dalšími informacemi, které jste jim poskytli nebo které získali v důsledku toho, že používáte jejich služby.
Používáme nezbytné cookies pro fungování webu a s tvým souhlasem také analytické a marketingové cookies.
Zajišťují základní funkce, bezpečnost a služby, které sis vyžádal. Nelze je vypnout.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| ITnetwork | ITnetwork | Provoz webu, relace, přihlášení a uložení nastavení cookies. | PHPSESSID, auth_token, sid, itn_consent_impression, __Host-itn_consent | Relace až 1 rok |
| Google Tag Manager | Správa značek a načítání měřicích nástrojů webu. | Žádné | Neukládá se | |
| Google Fonts | Načítání typografie webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google Hosted Libraries | Načítání potřebných knihoven a stylů webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google reCAPTCHA | Ochrana formulářů a webu před zneužitím. | _GRECAPTCHA, rc::a, rc::b, rc::c, rc::f | Relace až 180 dní | |
| YouTube | Přehrávání vloženého video obsahu. | localStorage, IndexedDB; cookies after playback interaction | Relace až trvalé úložiště | |
| Vimeo | Vimeo | Přehrávání vloženého video obsahu. | __cf_bm, _cfuvid, vuid, localStorage, IndexedDB | Relace až 2 roky |
| Facebook Login | Meta | Přihlášení pomocí účtu třetí strany. | Úložiště řízené poskytovatelem | Relace až 1 rok |
| GoPay | GoPay | Zpracování uživatelem vyžádané platby. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
Pomáhají nám porozumět používání webu a zlepšovat ho.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Analytics 4 | Měření návštěvnosti a používání webu. | _ga, _ga_* | Až 2 roky | |
| Microsoft Clarity | Microsoft | Měření návštěvnosti a používání webu. | _clck, _clsk, _cltk | Relace až 1 rok |
Slouží k měření kampaní, personalizaci reklamy a marketingové komunikaci.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Ads | Měření kampaní, reklama a remarketing. | _gcl_au, _gcl_ls | Relace až 90 dní | |
| Meta Pixel | Meta | Měření kampaní, reklama a remarketing. | _fbp, _fbc, localStorage | Až 90 dní |
| Sklik | Seznam.cz | Měření kampaní, reklama a remarketing. | retargeting, sid, szn:* | Relace až trvalé úložiště |
| LinkedIn Insight | Měření kampaní, reklama a remarketing. | bcookie, li_gc, lidc, __cf_bm | Relace až 1 rok | |
| Ecomail | Ecomail.cz | Měření kampaní, reklama a remarketing. | ecmid, Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
| Atribuce kampaní ITnetwork | ITnetwork | Přiřazení návštěvy a objednávky ke kampani. | campaign_clid[*], user_session_context | Až 1 rok |
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Vec prvni: doporucuji promennou sdilenou mezi vlakny (i kdyz jen jedno vlakno zapisuje a ostatni ctou) oznacovat vzdy jako volatile, za urcitych okolnosti by ctena promenna mohla vracet stale stejnou hodnotu, i kdyz by se v zapisovacim vlakne jeji hodnota menila.
Vypada to, ze se v hlavnim vlakne z pameti do registru nacte aktualni hodnota promenne count_b - treba je tam dejme tomu hodnota 13, v tu chvili se vlakno uspi (stav registru procesoru se ulozi), rozebehne se vlakno na pozadi, zvysi postupne v nekolika cyklech count_b treba na 20, vlakno na pozadi se uspi, zase se spusti prvni (obnovi se stav z registru, kde je ulozena stara hodnota 13), zavola se vypis do konzole, vypise se 13 a pak se zase v dalsim cyklu tveho while nacte do registru z pameti uz spravna hodnota, takze uz se pak vypisuje spravna.
Ha, tak jsem se nechal oklamat, vypada to, ze problem je stejny, ale v jinem
miste, vypada to, ze je to jen ve vypisu konzole 
Vypis do konzole je ve skutecnosti spousta instrukci, takze to vetsinou vlakno prerusi temer vzdy nekde v jejim volani, takze je tam stara hodnota promenne, protoze int hodnoty se v c# obvykle predavaji hodnotou - takze se jen vytvori kopie hodnoty promenne.
Mám ještě druhou začátečnickou otázku...
Když v kódu ošetřím kritické části následovně
<code>
static object zamek = new object();
..
..
lock (zamek)
{
// inkrementace číteče
// výpis stavu čítače
}
</code>
pak počítání funguje přesně. Jen pořád nerozumím konstrukci
"lock".
Jak třída pozná, že chci uzamknout proměnné cnt_f,cnt_b,... když jako
parametr zámku uvedu obecný objekt 
Chápal bych něco jako lock(this) pro celou třídu, nebo lock(a,b) pro dané
proměnné...
A tohle má být co?
private void pocitej()
{
while (true)
{
if (count_b < 100)
count_b++;
else
break;
//Thread.Sleep(10);
Console.WriteLine("Vlákno na pozadí: {0}", count_b);
}
To neumíš napsat normální cyklus?
private void pocitej()
{
while (count_b < 100)
{
count_b++;
//Thread.Sleep(10);
Console.WriteLine("Vlákno na pozadí: {0}", count_b);
}
Volatile na všechno nestačí. Lepší je používat thread-safe metody a kolekce.
Volatile na všechno nestačí, ale když zapisuje jen jedno vlákno a ostatní vlákno/vlákna jen čtou, tak obvykle není potřeba nic synchronizovat.
lock nezamyká objekty, ale části kódu.
Části kódu, které jsou pozamykané stejným zámkem nikdy nebudou probíhat najednou, (ani když ve dvou vláknech spustíš ten samý kód, tak není možné, aby ty zamčené části běžely najednou).
ad Kit:
není třeba se pohoršovat, ten kód je pouze testovací a cykly jsem postupně
zapisoval několika způsoby, když jsem ladil přepínání vláken..
ad Satik:
volatile jsem doteď ani nikdy nepoužil, v normální literatuře (basic skill)
se o ní zmiňují sotva okrajově, pokud vůbec.
"Části kódu, které jsou pozamykané stejným zámkem nikdy nebudou
probíhat najednou"
Princip zámku je mi jasný, nerozumím syntaxi. Pokud by to bylo jak říkáš,
pak by se zámek používal spíš s parametrem "jméno", nebo ne?
V CZ překladu na http://www.albahari.com/threading/ str.21 autor píše "V
příkladu nahoře chráníme obsah metody Go(), a tím pádem i obsah
proměnných val1 a val2" (totéž co u mě lock, count_f a count_b). Ta
formulace mi vůbec nedává smysl 
Volatile se používá kvůli tomu, že překladač občas používá
nějaké optimalizace, které můžou ve vícevláknových aplikacích nadělat
problémy - například dejme tomu, že máš proměnnou
cekat typu bool nastavenou na true
a kód
while (cekat)
{
nejaky kod, ktery promennou cekat vubec nepouziva
}
pokud proměnná cekat není volatile a překladač tedy neví, že se její obsah někde jinde může změnit, tak se ten cyklus může zoptimalizovat na rychlejší variantu:
if (cekat)
while (true)
{
...
}
a pak by změna hodnoty proměnné cekat na false v jiném vlákně ten cyklus nezastavila.
Ten parametr u zámku - zamykací objekt se právě používá místo jména.
"V CZ překladu na http://www.albahari.com/threading/ str.21 autor píše "V příkladu nahoře chráníme obsah metody Go(), a tím pádem i obsah proměnných val1 a val2" (totéž co u mě lock, count_f a count_b)"
Zobrazeno 11 zpráv z 11.