.[ ČeskéHry.cz ].
Synchronizace :: dereference

 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 26. prosinec 2011, 19:58:22    Předmět: Synchronizace :: dereference Odpovědět s citátem

Zdravím,

hraji si tu s mou semestrálkou na sítě a narazil jsem na něco, u čeho si nejsem vůbec jistý, zda se tím zabývat.

Jde mi zkrátka o to, že všem vláknům hráčů předám ukazatel na game manager, jeho metody obsahují nějakou synchronizaci (mutexem)...
Když nějakou zavolám, třeba takto: obj->fn(); tak je to stejné jako kdybych napsal (*obj).fn(); ... používá se tedy dereference...
No a mě zajímá, co se děje, když dochází k dereferenci...konkrétně v případě, že budu toto volat z více vláken...nemůže tam dojít k nějakému nesynchronizovanému přístupu nebo tak něco?

Díky. S vlákny si hraji chvilku, takže si nejsem vůbec jistý...
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Tringi



Založen: 28. 07. 2007
Příspěvky: 290

PříspěvekZaslal: 26. prosinec 2011, 20:24:53    Předmět: Odpovědět s citátem

Pakliže ten obj pointer předáváš, zůstává stejný, tak se ničeho obávat nemusíš.
Normálně kompilátor zná adresu objektu a přímo s ní pracuje, tady si ji jen musí nejprve přečíst z proměnné, nic na co bys musel být zvlášť opatrný.

Funkce fn pak samozřejmě musí, v nejjednodušším případě být kanonicky uzavřena v mutexu (nebo kritické sekci), nebo lépe (je-li těch vláken hodně) synchronizovat přístup ke sdíleným datům.
_________________
WWW | GitHub | TW
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Quiark



Založen: 29. 07. 2007
Příspěvky: 816
Bydliště: Chlívek 401

PříspěvekZaslal: 27. prosinec 2011, 00:45:08    Předmět: Odpovědět s citátem

Synchronizovaný přístup do paměti je potřeba jen když do ní ve kterémkoliv vlákně zapisuješ (a u lock-free ani to ne Wink. Při dereferenci se čte, nic se nezapisuje, takže není problém.

EDIT: upřesnění
_________________
Mám strach


Naposledy upravil Quiark dne 27. prosinec 2011, 09:28:35, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 27. prosinec 2011, 03:38:05    Předmět: Odpovědět s citátem

To není tak úplně přesné. I čtení je třeba chránit zámkem v některých případech, viz níže.

Pokud je proměnná read-only, přístup k ní nepotřebuje žádné zámky. Read-only proměnná je i taková, která se nastaví jednou při inicializaci a během běhu více vláken se už nemění.

Pokud se proměnná může měnit během běhu více vláken, jakýkoliv přístup k ní musí být chráněný zámkem a to i když se z ní jen čte. Ten zámek je svázaný s tou proměnnou a měl by pouze chránit přístupy k té proměnné. Samozřejmě větší kus kódu, který nad tou proměnnou pracuje, by měl být celý chráněný zámkem po celou dobu jeho běhu.

Místo zámků se dají použít i atomické operace, ale jen někdy. Některé operace jsou atomické defautně, ale toho se taky dá využít jen někdy.

Některé datové struktury fungují bez zámků, ale tam jsou využívány triky, jak toho dosáhnout. Typický příklad je ring buffer, kde jedno vlákno pouze čte a druhé pouze zapisuje.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Tringi



Založen: 28. 07. 2007
Příspěvky: 290

PříspěvekZaslal: 27. prosinec 2011, 04:26:51    Předmět: Odpovědět s citátem

...což je dost komplikovaná problematika, kde i programátoři s roky zkušeností snadno udělají heisenbug (chyby, které se projeví zřídka a náhodně). Guilty as charged Embarassed

Navíc dnes, na moderních OS, v 99% ani korektní lock-free synchronizací nic nezískáš. Jelikož se zabývám především vývojem nad Windows, tak můžu jako příklad uvést kritické sekce: Ty byly v každé major verzi totálně překopány a stávající verze (Vista a novější) v ideálním případě (žádné jiné vlákno není uvnitř dané kritické sekce) trvá jen pár instrukcí, provede se de facto atomická operace, bez context-switche, bez přepnutí do kernel módu. Věřím že podobně vyladěné to za ty roky mají všechny OS dnes.
_________________
WWW | GitHub | TW
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 27. prosinec 2011, 06:57:53    Předmět: Odpovědět s citátem

Podle mě to není moc komplikované, ale běžně se setkávám s lidmi, kteří programují kód pro multivláknové prostředí jako by tam bylo jen jedno vlákno, a tváří se, jako by všechno bylo v pořádku.

Akorát jsi nevysvětlil, proč v 99% případů lock-free kódem nic nezískáš. Jenom jsi to zmínil a pak jsi se začal bavit o implementaci Windows. Myslel jsi to tak, že mutex interně využívající atomické operace není o moc horší než použití atomické operace přímo (což se běžně používá pro implementaci lock-free kódu)?

Zásadní rozdíl bych viděl v tom, že když dojde ke kolizi dvou vláken při vstupu do mutexu, tak jedno vlákno se uspí a tedy dojde ke context switchi. Pokud se stejná kolize stane u atomické instrukce, tak ke context switchi dojít nemusí, jenom se vykonávání vlákna pozastaví hardwarem na dobu nezbytně nutnou. Další věc je, že vstup do mutexu má nějakou režii (volá se tam na to nějaká funkce a operuje se tam s nějakou pomocnou strukturou), zatímco atomická operace přímo odpovídá instrukci v asm. (možná jen na Windows je ještě obalena ve WinAPI funkci)
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 27. prosinec 2011, 09:04:28    Předmět: Odpovědět s citátem

Marek napsal:
zatímco atomická operace přímo odpovídá instrukci v asm. (možná jen na Windows je ještě obalena ve WinAPI funkci)


InterlockedIncrement apod.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 27. prosinec 2011, 09:48:35    Předmět: Odpovědět s citátem

Oki, takže tu dereferenci řešit nemusím? Předpokládám, že když je na levé straně [ obj->fn(); ], tak nedochází ke čtení ani zápisu do sdílené paměti, tudíž není třeba synchronizovat, jo?
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 27. prosinec 2011, 10:56:53    Předmět: Odpovědět s citátem

samozrejme ze dochazi ke cteni ze sdilene pameti - nicmene je to misto, ze ktereho se pouze cte -> neni treba resit synchronizaci

mam ale obecne pocit ze moc nevis na co a jak se synchronizace pouziva -> bylo by dobre trochu vice neco nacist ...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 27. prosinec 2011, 11:07:38    Předmět: Odpovědět s citátem

rezna> Jo, to jsem myslel.

VODA> To nejde tak přímo určit z jednoho fragmentu kódu. Volání funkce samo o sobě problematické není, ale uvnitř fn už to může být úplně jinak. Samozřejmě dochází minimálně ke čtení (sdílené) paměti. Všechna paměť procesu je vždy sdílená mezi vlákny toho procesu. (teď si nejsem jistý, jak je to se zásobníkem) EDIT: rezna byl rychlejší Smile
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 27. prosinec 2011, 11:47:03    Předmět: Odpovědět s citátem

Oki, mě konkrétně zajímalo volání funkce samotné. Nic jiného. Jen mě tam mate ta dereference...
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
OndraSej



Založen: 28. 07. 2007
Příspěvky: 767
Bydliště: Brandýs nad Labem

PříspěvekZaslal: 27. prosinec 2011, 12:10:45    Předmět: Odpovědět s citátem

VODA> volani nevirtualni metody je v pohode vzdy (adresa metody je znama v dobe prekladu a jen se ji preda ukazatel na objekt a nic se nedereferencuje). Volani virtualni metody je v pohode, pokud je zarucene, ze ten objekt je nazivu (je potreba jit do tabulky virtualnich metod, takze tam se neco dereferencovat musi).
_________________
http://trionteam.net
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna