Vlákna - synchronizace – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Vlákna - synchronizace – C / C++ – Fórum – Programujte.comVlákna - synchronizace – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
crazy
~ Moderátor
+10
Grafoman
21. 3. 2012   #1
-
0
-

Zdravím,

řeším klasický problém producent - konzument. Producent zapisuje data do fronty ( mám LIFO ) a konzumenti z ní vybírají... Jde mi o to, že vím jak synchronizovat takovouto úlohu, pokud znám předem velikost fronty (pomocí dvou semaforů), ale co když tu velikost neznám a fronta se mi dynamicky zvětšuje?

Nahlásit jako SPAM
IP: 2001:718:2:31:1e75:8ff:fe...–
All you need is vision and time.
Reklama
Reklama
KIIV+42
God of flame
21. 3. 2012   #2
-
0
-

sak zamkni mutex, zjisti velikost fronty, odeber prvek, odemkni...   u pridavajiciho threadu zase zamknout, pridat, odemknout---  tak aby data zustavaly zamceny co nejkratsi dobu

Nahlásit jako SPAM
IP: 93.91.152.–
Program vždy dělá to co naprogramujete, ne to co chcete...
crazy
~ Moderátor
+10
Grafoman
21. 3. 2012   #3
-
0
-

#2 KIIV
zatím to dělám tak, že přidám prvek do fronty -> zvýším hodnotu semaforu -> konzument čeká na semaforu -> zpracuje prvek z fronty a zase hodnotu semaforu sníží... jenže pak mám problém, že někdy (zhruba 1/10 pokusů) se mi neukončí nějaká vlákna (prostě zůstanou viset na semaforu v konzumentovi) ... ( samozřejmě zamykám mutexama přidání a odebrání prvku z fronty... )

Nahlásit jako SPAM
IP: 2001:718:2:31:1e75:8ff:fe...–
All you need is vision and time.
zlz
~ Anonymní uživatel
634 příspěvků
22. 3. 2012   #4
-
0
-

Asi budeš muset ukázat kód, nedovedu si představit, jak se to děje jen někdy. Pokud konzumenti čekají na semaforu, tak ho samozřejmě musíš pro všechny zvednout, aby se probrali.

producent()
{
    while ((prvek = produkuj()) != null)
    {
        put(prvek);
        sem++;
    }

    sem += pocetkonzumentu;
}


konzument()
{
    while (true)
    {
        wait(sem);
        if ((prvek = get()) == null)
            break;
        konzumuj();
    }
}
Nahlásit jako SPAM
IP: 213.211.51.–
devilfish0
Stálý člen
22. 3. 2012   #5
-
0
-

No nevies velkost fronty, lenze fronta je dynamicka datova struktura takze ju mozes zvacsovat pokial ti nedojde pamat nie? Tak si urc nejaku konstantu - velkost ktoru nechces presiahnut a potom to zosynchronizuj pomocou dvoch semaforov a mutexu

semafor semPocet = 0;
semafor semVelkost = N;
semafor mutex = 1;

procudent()
{
	semVelkost.wait();
	mutex.wait();
	fronta.add();
	mutex.signal();
	semPocet.signal();
}

konzument()
{
	semPocet.wait();
	mutex.wait();
	fronta.get();
	mutex.signal();
	semVelkost.signal();
}

Kde semPocet strazi aby konzument pockal ak je fronta prazdna, semVelkost strazi aby producent neprodukoval ak by mal presiahnut tebou stanovenu velkost a mutex na osetrenie KO

Nahlásit jako SPAM
IP: 188.121.172.–
crazy
~ Moderátor
+10
Grafoman
22. 3. 2012   #6
-
0
-

díky za rady...

ale já bych potřeboval, když mi skončí producent a fronta bude prázdná, tak bych potřeboval ukončit všechny konzumenty... to mi zatím dělá celkem problém (většinou 1/10 pokusů mi neskončí jedno vlákno)

Nahlásit jako SPAM
IP: 2001:718:7:204:73:4460:55...–
All you need is vision and time.
liborb
~ Redaktor
+18
Guru
22. 3. 2012   #7
-
0
-

Nejlíp ti odpověděl zlz a má (zase) pravdu. Další obecná rada ... udělej si logování (stavy semaforů, vláken ...) do nezávislého okna (ala DbgView) nebo pokud to nechceš řešit :), tak zvedni počet na semaforu o víc než o počet konzumentů.

Nahlásit jako SPAM
IP: 78.80.52.–
Midnight
~ Anonymní uživatel
78 příspěvků
24. 3. 2012   #8
-
0
-

Můžeš to řešit tak, že když producent skončí a přestane produkovat, zvedne hodnotu na semaforu o počet vláken.

Vlákna pak budou mít v kódu to, že pokud queue.pop ( ) == NULL, tak skončí.

Tedy pokud nastane situace, že všechny věci z fronty budou zpracovány, vláknům začne fronta fracet NULLy a tím poznají, že se mají ukončit.

Nebo dáš do producenta nějakou smyčku se sleepem a až bude fronta prázdná, tak ty vlákna odstřelíš. Ale to jen, jestli děláš úkol do školy, kterej ti kontroluje stroj a ne učitel  

Nahlásit jako SPAM
IP: 92.62.224.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 83 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý