Zapoctovy test, 10.2.2009 [16:00]

tommy at 2009-02-11 13:17:36

Zadanie v skratke bolo o k-cestnom triedeni zlievanim (k-way mergesort, triedenie v externej pamati) s obmedzenou pamatou na vnutorne triedenie. Na prvy pohlad easy. Na druhy ( http://dsrg.mff.cuni.cz/~malohlava/teac ... 2.2009.pdf ) uz ani velmi nie, kedze bolo treba pouzit paralelne vypocty pouzitim threads. Pracu s vlaknami, paralelnym vypoctom a spajanim vlakien som na cvikach akosi nezaregistroval, zeby sme sa tomu venovali a na prednaskach sa tomu venuje len par slajdov. Je pravda ze niektori to dali, ale dost z nas nemalo ani sajnu o threadovani a ucilo sa to on the fly na zapocte. Nemohol by mi niekto uviest priklad prace s vlaknami, resp. ako sa to malo riesit?

string someParameter = "hello";
for(int i =0; i < 10; i++)
{
   DoSomeCounting(i, someParameter);
}
DoSomeOtherCountingDependingOnResultsFromForCycle();

Ako toto prevediem na paralelny vypocet kde v kazdom vlakne bude jedno volanie procedury DoSomeCounting(i,someParameter) a ked vsetky tieto vlakna skoncia svoju pracu mozem pokracovat v DoSomeOtherCounting..() ??? Hladal som to na nete, ale neuspesne. Diky za odpovede :)

Osiris at 2009-02-11 13:41:38

Nešlo by prostě jenom udělat potomka Thread a třeba v konstruktoru předávat parametry ?

string someParameter = "hello";
List<MyThread> l = new List<MyThread>();
for(int i =0; i < 10; i++)
{
   MyThread t = new MyThread(i, someParameter);
   l.add(t);
   t.start();
}

foreach (MyThread t in l)
{
   t.Join();
}

DoSomeOtherCountingDependingOnResultsFromForCycle();
tommy at 2009-02-11 13:49:00

pokial viem, trieda Thread je sealed, takze od nej neviem dedit ...

Osiris at 2009-02-11 13:54:32

tommy wrote:pokial viem, trieda Thread je sealed, takze od nej neviem dedit ...

Tak to udělej jednoduše tak, že budeš mít seznam parametrů v nějakém Listu, udělej si Runnable a parametry nepředávej v cyklu, ale parametry budou předávány přes ten list (je ho nutné zamykat).

Jakobicek at 2009-02-12 04:34:37

pokud vím tak lze vytvořit třídu MyThreadCaller-je to vlastne analogie funktoru z C++ - která bude mít metodu DoSomething(void). Parametry ji předáš pomocí konstruktoru MyThreadCaller(filenames, ways a cokoliv dalsiho...). Nasledne vytvoris instanci tedle tridy nazveme ji MojeVlakno predas ji patricne parametry. Vytvoris instanci ThreadEntryPoint - vstupní bod vlákna, kterému předáš jako parametr MojeVlakno.DoSomething - delegat na tu metodu co chces pustit ve vlakne a vesele pustis to vlakno... dulezite je mit ty parametry tak aby je vlastnilo to vlakno samo nebo teda ta vlaknova trida... takze odpada zamykani a jine legracky...

Edit: zjistil jsem ze existuje delegat ParametrisedThreadStart, kteremu muzete pridat na zacatek vlakna parametr typu object... zde prezentovane reseni je vsak funkcni a pravdepodobne i ciste nebot se tak vyhneme pretypovani

MyThreadCaller
{
private ruzneParametry;
public DoSomething();
public MyThreadCaller(ruzneParametry);


}

PustVlakna()
{
List<Thread> vlakna=new List<Thread>();
for(i=0;i<max;++i)
   {
   MyThreadCaller Volac=new MyThreadCaller(parametry);//predame vlaknum parametry
   ThreadEntryPoint te=new ThreadEntryPoint(Volac.DoSomething);//nastavime vstupni bod do vlakna
   Thread t=new Thread(te); t.Start();//pustime vlakna
   vlakna.add();//nekam to ulozime
    }
foreach(Thead x in vlakna)
   {
   x.Join();//pockame az dobehnou
   }
PocitejDal();
}
Anonymous at 2009-02-16 11:52:10

Uznaval aj take veci, ze ked X < K, tak sa spravilo X-cestne triedenie a nebabralo sa s tym? :P