NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
Avatar
švrčajs
Člen
Avatar
švrčajs:13.4.2016 10:05

Zdravím,
mám takový menší problém, ve škole si začínáme hrát s vlákny a dostal jsem takovou menší úlohu. Jedná se o naprogramování "šílené menzy", kde kde student nikdy nesmí sedět u stolu sám :D napsal jsem svůj program, ale mám problém s tím, že vlákna mezi sebou nekomunikují.

Přikládám i zadání, předem říkám, že nechci, aby to někdo naprogramoval za mě :D jde mi spíše o nějakou radu, případně jestli vůbec postupuji správně, viz kod.. (zasekl jsem se hned na začátku)

Studenti chodí do menzy jist. Po vstupu do menzy student zavolá funkci getFood() a je připraven jíst, poté zavolá dine() — to sedí u stolu, po zavolání dine() je připraven odejít, a na konci zavolá leave() — odchází z menzy. Synchronizační omezení: Student nikdy nesedí u stolu sám. Student je považován u stolu za samotného, pokud platí alespoň jedna z následujících podmínek:
student zavolá dine(), ale nikdo nesedí u stolu a ani nikdo není připraven jíst,
student zavolá dine(), a všichni, kdo zavolali dine(), už také zavolali leave() (během toho, co student sedí u stolu, takže tam zůstane sám).
Funkce getFood(), dine(), leave() nesmí být použity k synchronizaci (lze je využít např. k výpisu na terminál, pro vložení volání sleep, případně nechat prázdné).Každého studenta simulujte samostatným vláknem. Odevzdejte algoritmus v pseudokódu a jeho implementaci.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace ukol2
{
    class Program
    {

        static private readonly object theLock = new object();
        static private volatile int majiciJidlo = 0;
        static private volatile int jedici = 0;
        static private volatile int cekajiciNaOdchod = 0;

        static void getFood()
        {
            Console.WriteLine("Vydano jidlo(UHO)");
            Thread.Sleep(2000);
        }
        static void dine()
        {
            Console.WriteLine("Začina baštit");
            Thread.Sleep(2000);
            Console.WriteLine("Dobaštil");
        }
        static void leave()
        {
            Console.WriteLine("Ochází :( ");
            Thread.Sleep(2000);
        }

        static void doAction()
        {
            getFood();
            lock (theLock)
            {
                ++majiciJidlo;
            }


            while (true)
            {
                if (majiciJidlo >= 1 || jedici >= 1)
                {

                    lock (theLock)
                    {
                        --majiciJidlo;
                        ++jedici;
                    }
                    break;
                }
            }

            while(true)
            {
                if (cekajiciNaOdchod > 0 || jedici > 0 )
                {
                    dine();
                    ++cekajiciNaOdchod;
                    break;
                }
            }



        }

        static int Main()
        {

            for (int i = 0; i < 10; i++)
            {
                Thread t1 = new Thread(() => {doAction(); });
                t1.Start();

            }

            Console.ReadLine();
                return 0;
        }


    }
}
 
Odpovědět
13.4.2016 10:05
Avatar
švrčajs
Člen
Avatar
švrčajs:13.4.2016 11:12

Pohrál jsem si s tím a snad mám i funkční řešení :D viz kod..

class Program
{

    static private readonly object theLock = new object();
    static private  int majiciJidlo = 0;
    static private  int jedici = 0;
    static private  int cekajiciNaOdchod = 0;

    static void getFood()
    {
        Console.WriteLine("Vydano jidlo(UHO) {0}", Thread.CurrentThread.ManagedThreadId.ToString());

    }
    static void dine()
    {
        Console.WriteLine("Začina baštit {0}", Thread.CurrentThread.ManagedThreadId.ToString());
        Thread.Sleep(2000);
        Console.WriteLine("Dobaštil {0}", Thread.CurrentThread.ManagedThreadId.ToString());
    }
    static void leave()
    {
        Console.WriteLine("Ochází :( {0}", Thread.CurrentThread.ManagedThreadId.ToString());

    }

    static void doAction()
    {

        getFood();
        lock (theLock)
        {
            ++majiciJidlo;
        }

        //ověření, zda na jedení čekají dva, popř, jeden sedí u stolu => nebude u stolu sám...
        while (true)
        {
            if (majiciJidlo > 1 || jedici > 1)
            {
                //ověření, zda na jedení čekají dva, popř, jeden sedí u stolu => nebude u stolu sám...
                lock (theLock)
                {
                    --majiciJidlo;
                    ++jedici;
                }
                break;
            }
        }

        while(true)
        {
            if (cekajiciNaOdchod > 0 || jedici > 0 )
            {
                dine();
                ++cekajiciNaOdchod;
                break;
            }
        }

        leave();
        --cekajiciNaOdchod;



    }


    static int Main()
    {

        for (int i = 0; i < 4; i++)
        {
            Thread t1 = new Thread(() => {doAction(); });
            t1.Start();

        }

        Console.ReadLine();
            return 0;
    }


}

Ale chtěl jsem se zeptat, v knížce jsem našel příklad, kde se využívají semafory, pro synchronizaci.. Jednalo se o vstup do kina, kde byl omezen maximální počet diváků. Chtěl jsem se zeptat, jestli by šli semafory využít i na můj příklad, případně poprosit alespoň o nějakou ideu, jak to udělat

 
Nahoru Odpovědět
13.4.2016 11:12
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.