Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno C - synchronizace vlaken nad spojovym seznamem

Ahoj, mam spojovy seznam ze struktur a 10 vlaken, ktere se spojakem pracuji. Nekdy jen nejake, nekdy vice, nekdy mene - neni ted dulezite. Jde mi o to, ze musim nejakym zpusobem zamykat ten spojak, aby mi do nej (jako do kriticke sekce) nelezlo vice vlaken.
Jenze - prijde mi blbost zamykat uplne cely spojak, kdyz chce jedno vlakno prepsat pouze jednu hodnotu v jedne strukture.
Lze nejakym zpusobem zamknout pouze tu jednu konkretni strukturu?

Struktura

struct game{
  int id;
  short active;
  struct player *player1;
  struct player *player2;
  struct game *next;
  struct game *previous;
};
Předmět Autor Datum
Nevím, jestli je to ideální, ale napadlo mě: Co kdybys zamykal nějakou proměnnou (nejspíš ukazatel),…
Niko Bellic 09.01.2014 23:07
Niko Bellic
Tyjo, nejak nemuzu pochopit, jak jsi to myslel. Zkus to konkretne na te strukture ci spojaku. Co mys…
freez2 09.01.2014 23:17
freez2
No záleží, jak to máš přesně implementované, ale řekněme, že vlákno chce pracovat s nějakou položkou…
Niko Bellic 09.01.2014 23:28
Niko Bellic
Jo uz jsem ASI pochopil. Ze do nejake promenne si ulozim strukturu ze spojaku, se kterou chci pracov…
freez2 09.01.2014 23:34
freez2
Do proměnné si uložíš jen ukazatel na tu strukturu a můžeš ho porovnávat s ukazatelem, kam chceš při…
Niko Bellic 09.01.2014 23:40
Niko Bellic
To je vlastne pravda, ze kdyz vim, ze mam 10 vlaken, ze bude vzdy obsazeno max 10 struktur - a to by…
freez2 09.01.2014 23:45
freez2
Ano, přesně taková je úvaha :-) A protože se v nich bude vyhledávat asi docela často, můžeš to uděla…
Niko Bellic 09.01.2014 23:52
Niko Bellic
Co by v tom pripade bylo klicem, resp. hodnotou uzlu?
freez2 10.01.2014 00:02
freez2
Hodnota uzlu by byla ukazatel na strukturu a klíč v podstatě cokoliv, aby byl pro každou položku jin…
Niko Bellic 10.01.2014 00:19
Niko Bellic
Nebylo by misto implementace binarniho stromu jednodussi projit proste 10ti prvkove pole? :)
freez2 10.01.2014 00:23
freez2
Bylo, jen to bude trochu neefektivní.
Niko Bellic 10.01.2014 00:26
Niko Bellic
Každá položka bude mať svoj vlastný zámok, ktorý budeš používať na synchronizáciu práce práve s tou…
los 10.01.2014 08:28
los
To je lepsi reseni nez jsme vymysleli (kolega vymyslel) predtim... Diky. poslední
freez2 10.01.2014 10:48
freez2

Nevím, jestli je to ideální, ale napadlo mě: Co kdybys zamykal nějakou proměnnou (nejspíš ukazatel), který by představoval položku v seznamu, se kterou pracuje nějaké vlákno? Pak by každé vlákno nejdřív porovnalo ten ukazatel s tím, kam chce přistoupit a případně by se zařadilo do fronty, nebo by mohlo přistoupit k položce, ke které chce, protože s ní žádné jiné vlákno nepracuje.

No záleží, jak to máš přesně implementované, ale řekněme, že vlákno chce pracovat s nějakou položkou v seznamu. Najde ji a ukazatel na ni vloží do nějaké proměnné (ta bude v kritické sekci). A pak s položkou pracuje. Jiné vlákno bude chtít tu stejnou položku, tak si ji najde, ale před tím zkontroluje, jestli ten ukazatel na ni není stejný, jako ten v kritické sekci. Pokud je, tak se zařadí do fronty (my řešili něco podobného s pomocí unixových semaforů). Jak původní vlákno skončí, tak ten ukazatel smaže a pustí jiné vlákno, které čeká třeba na nějakém semaforu. Ale ber to jako úvahu. Nevím, jestli tam nevznikne třeba race condition apod. To chce nad tím sednout a promyslet všechny možnosti.. :-)

Jo uz jsem ASI pochopil. Ze do nejake promenne si ulozim strukturu ze spojaku, se kterou chci pracovat. Tim jina vlakna poznaji, ze v te promenne neco je, tak se nad ni zablokuji, dokud nebude volno. To mi ale prijde, ze neresi problem, kdyz mam napr. 10 struktur, jedno vlakno chce ke strukture 3, druhe ke strukture 8. "Promennou" obsadilo vlakno pro strukturu 8, tim padem druhe vlakno, ktere chce ke strukture 3, musi cekat. Je to tak?

Do proměnné si uložíš jen ukazatel na tu strukturu a můžeš ho porovnávat s ukazatelem, kam chceš přistoupit. Pak chce třeba vlákno přistoupit ke struktuře 8, mrkne do kritické sekce, tam je třeba ukazatel na strukturu 3, tak s tou osmičkou může klidně pracovat a zase někde uložit informaci, že s ní pracuje. Asi teda nebude stačit jen jeden ukazatel, ale tolik, kolik je vláken. Možná..

Každá položka bude mať svoj vlastný zámok, ktorý budeš používať na synchronizáciu práce práve s tou jednou položkou. Okrem toho, budeš mať jeden spoločný zámok pre prácu so zoznamom (pridávanie, uberanie, iterovanie).

Čiže napr.:

struct game{
  int id;
  short active;
  mutex *list_mutex;
  mutex *item_mutex;
  struct player *player1;
  struct player *player2;
  struct game *next;
  struct game *previous;
};

Pri vytváraní prvej položky zoznamu vytvoríš zámok list_mutex, ktorý pri pridávaní ďalších položiek budeš kopírovať tým položkám. Pri vytváraní každej položky si vytvoríš nový zámok item_mutex.

Zpět do poradny Odpovědět na původní otázku Nahoru