Úvod
V dnešní době, kdy dvou i vícejádrové procesory jsou naprosto běžné by bylo škoda nevyužít tento potenciál. Koncept multithreadingu je znám už dlouho, ale není tomu tak dávno co vícejádrové procesory byly doménou pouze serverových systémů.
V oblasti vývoje aplikací v jazyce Visual Basic bylo poprvé možné plnohodnotně vyvíjet vícevláknové aplikace s příchodem Visual Basicu 7.0 (Visual Basic .NET) v roce 2002. Toto bylo obrovským přínosem pro Visual Basic vývojáře, kterým se tímto dostal do ruky mocný nástroj.
Co je to Thread (vlákno)?
Vlákno je posloupnost instrukcí, které můžou být zpracovávány současně s dalšími vlákny. Je to cesta jak rozdělit program do více paralelně (nebo pseudo-paralelně) běžících úloh.
Je třeba rozlišovat mezi pojmy vlákno a proces. Proces obsahuje jedno nebo více vláken. Vlákna uvnitř procesu mohou vzájemně sdílet stejná data, procesy nikoliv.
Co je to Multithreading (vícevláknové zpracování)?
Vícevláknové zpracování obecně funguje na principu rozdělování času - každému vláknu je přidělen určitý čas procesoru (jehož délka závisí například na prioritě vlákna) a po uplynutí procesor přepne na další vlákno. Přepínání mezi vlákny probíhá tak rychle, že máme dojem že vše běží současně. Velmi důležitý je fakt, že procesor se může přepnout na další vlákno uprostřed zpracování nějaké operace (v dalším kole se ve zpracování pokračuje tam kde se skončilo) a to je právě hlavní důvod k synchronizaci o které budu psát později. Systém který se stará o přidělování času vláknům se nazývá Scheduler (plánovač - pozor, neplést s programem Plánovač úloh). Jiný způsob dosažení vícevláknového zpracování je tzv. Multiprocessing (souběžné zpracování), který využívá všechny procesory v systému ke skutečně paralelnímu zpracování - máte-li dvě a více jader, můžete zpracovávat dvě a více úloh současně. Existují dva způsoby multithreadingu - preemptivní, kde čas přiděluje systém (běžně používaný způsob) a kooperační, kdy je na vláknu samotném aby předalo řízení dál (používalo se ve Windows 3.x).
Hlavní problémy při psaní vícevláknových aplikací
Race condition
Race condition je nežádoucí stav, ke kterému dochází v momentě, kdy jedno nebo více vláken přistoupí ke sdíleným datům zatímco jiné vlákno s těmito daty již pracuje. Tato sdílená data se nazývají kritická oblast, část programu která pracuje s daty v kritické oblasti a kterou je třeba dokončit jako celek se nazývá kritická sekce.
Deadlock
Noční můra každého programátora. Deadlock nastává v momentě, kdy dokončení operace A je podmíněno dokončením operace B a zároveň dokončení B je podmíněno dokončením A. Jinak řečeno A čeká na B a B čeká na A, program tedy uvázne v mrtvém bodě. Ve většině případů je to způsobeno nesprávným použitím synchronizačního objektu ReaderWriterLock, který se stará o uzamykání přístupu ke sdíleným datům pro jednotlivá vlákna. Najít a odstranit Deadlock je velmi obtížné, obzvlášť u rozsáhlých projektů.
Atomické operace
Atomickou operací nazýváme takovou funkci, u které je na 100% zaručeno, že bude dokončena jako celek a že systém nepřepne na jiné vlákno uprostřed jejího zpracování. Takové funkce můžeme najít ve třídě System.Threading.Interlocked a jedná se o základní operace jako sčítání, inkrementace a dekrementace čísel a záměna čísel.
Příklad
Následující příklad vícevláknového zpracování představuje konzolovou aplikaci, která plní pole o velikosti 10 000 000 prvků náhodnými čísly. Aby byl vidět rozdíl délky zpracování, provádí se plnění pole nejprve hlavním vláknem a potom dvěma vlákny současně. Vzhledem k tomu, že příklad má být co nejjednodušší, neřeším zde synchronizaci přístupu ke sdíleným datům (pole náhodných čísel) do kterého zapisují obě vlákna současně. Výsledky se mohou na různých hardwarových konfiguracích lišit a na jednojádrových procesorech může být zpracování jedním vláknem dokonce rychlejší.
Imports System.Threading
Module Module1
'Pole pro naplnění náhodnými čísly (sdílená data)
Private numbers(9999999) As Integer
Sub Main()
'Nastaví název hlavního vlákna programu
'(potom je přehledně vidět v seznamu vláken při ladění)
Thread.CurrentThread.Name = "Main"
'Naplnit celé pole náhodnými čísly jen pomocí hlavního vlákna
ProcessNumbers(New Integer() {0, 9999999})
'Vytvoření dvou vláken které budou provádět metodu ProcessNumbers
'(každé vlákno nezávisle na sobě)
Dim numberProcessor1 As New Thread(AddressOf ProcessNumbers)
Dim numberProcessor2 As New Thread(AddressOf ProcessNumbers)
numberProcessor1.Name = "numberProcessor1"
numberProcessor2.Name = "numberProcessor2"
'Spuštění obou vláken s parametrem (počátek a konec plnění pole)
numberProcessor1.Start(New Integer() {0, 4999999})
numberProcessor2.Start(New Integer() {5000000, 9999999})
Console.ReadKey()
End Sub
'Metoda pro naplnění pole náhodnými čísly
'(musí odpovídat delegátu System.Threading.ThreadStart nebo
'System.Threading.ParameterizedThreadStart)
Private Sub ProcessNumbers(ByVal obj As Object)
Dim t0 As Date = Date.Now
'Přetypování z objektu na pole dvou čísel
'(počátek a konec plnění pole)
Dim indexes() As Integer = DirectCast(obj, Integer())
Dim randomizer As New Random()
For index As Integer = indexes(0) To indexes(1)
numbers(index) = randomizer.Next(Integer.MinValue, Integer.MaxValue)
Next
Console.WriteLine(String.Format("{0}: {1:N0} ms", Thread.CurrentThread.Name, Date.Now.Subtract(t0).TotalMilliseconds))
End Sub
End Module
Výstup ukázkového programu může vypadat takto:
Main: 1 563 ms
numberProcessor1: 1 094 ms
numberProcessor2: 1 328 ms
Znamená to, že zpracování jedním vláknem trvalo 1 563 ms a zpracování dvěma vlákny současně 1 328 ms (obě vlákna byla spuštěna téměř současně, takže je třeba vybrat větší hodnotu protože druhé vlákno skončilo dříve). Rozdíl je sice nepatrný, ale v případě že by se jednalo o mnohem náročnější výpočet než vytvoření náhodného čísla (například výpočet čísla Pi s vysokou přesností) by byl rozdíl daleko větší.
Co dál?
V dalším díle seriálu bych se chtěl věnovat především problému synchronizace, ale rád uvítám veškeré vaše návrhy co byste chtěli vědět ohledně vícevláknového zpracování.
Vývojář desktopových a mobilních aplikací.
Táto téma ma zaujíma
Datum: 22.5.2008 12:14
Autor: neregistrovaný (194.154.225.30)
Hodnocení autora: není
Příspěvků: 0
Nakoľko sa zatial zaoberám iba teóriou tejto problematiky, rad by som v budúcich dieloch videl trochu podrobnejší popis System.Threading. Ani s príkladu som úplne presne nepochopil, čo ktorý zápis robí.
Re: Táto téma ma zaujíma
Datum: 22.5.2008 13:55
Autor: neregistrovaný (194.228.45.222)
Hodnocení autora: není
Příspěvků: 0
Mno nejsem profik, ale je patrne ze je definovana funkce ProcessNumbers ktera plni pole v rozsahu od - do nahodnymi cisly.
Pak v hlavni funkci je zavolana tato funkce na naplneni v intervalu od 0 do 9 999 999. To znamena generuje deset milionu nahodnych cisel a zapisuje je do pole.
Pozdeji je prikazem Dim numberProcessor1 As New Thread(AddressOf ProcessNumbers) nadefinovan objekt (nebo trida nebo co to je) jako novy thread (vlakno),to same i pro druhy proces (Dim numberProcessor2 As New Thread(AddressOf ProcessNumbers)).
AddressOf podle me urcuje funkci ktera se timto pak spusti.
na dalsich dvou radcich jsou nove vytvorena vlakna pojmenovana...
No a na poslednich dvou radcich ridici funkce jsou tyto thready odstartovany, to znamena spustena funkce na naplneni pole nahodnymi cisly. Kazde vlakno ovsem plni pouze polovinu pole, a procesy probihaji temer od stejne chvile, takze by to melo byt rychlejsi na dvoujadrovem procesoru.
Me zajimaji spise tyto otazky. Bude zatez skutecne rozlozena mezi obe jadra procesoru (pripadne na serveru mezi oba procesory)? Nemuze se stat ze by aplikace zatizila jeden procesor 2x a druhy zustal volny? A pripadne jak poznam kolik jader procesor ma (pripadne kolik procesoru ma server?)
Kdyz bych planoval napriklad herni server ktery by melo obsazovat vice klientu (treba 200), je mozne rozdelit aplikaci napriklad na 200 threadu (pro kazdeho hrace)? Nebo musim programovat tak, abych vytvoril idealne presne tolik threadu kolik mam procesoru? To znamena ze u dvoujadroveho procesoru bych musel napsat aplikaci tak aby kazdy thread obsluhoval 100 klientu? Takze spis, bude prilis mnoho threadu velka zatez na CPU nebo to nevadi a rezie na obslouzeni tolika threadu neni tak vysoka?
Re: Táto téma ma zaujíma
Datum: 23.5.2008 17:59
Autor: neregistrovaný (194.228.45.222)
Hodnocení autora: není
Příspěvků: 0
Děkuji za odpovědi a za článek...
Proč sem se ptal, někde sem totiž viděl zdorjový kód jednoduchého HTTP serveru (nebo co to bylo zač) a tam při každém nově navazujícím spojení (připojující se klient k serveru) si server pro tohoto uživatele vytvořil nový thread. Pak v tom threadu spustil asynchronní čtení dat a jejich zpracovávání. Je jasné že u HTTP serveru se příliš mnoho klientů současně stahujících malé soubory nesejde, pokud webový server není příliš vytěžovaný, ale co například nějaký poštovní server (IMAP, POP3) nebo třeba FTP server nebo nejakej streamovací server? Tam pak lze předpokládat vyšší zátěž (streamováni souboru několika desítkám klientů (pokud pomineme fakt že tohle se většinou řeší přes UDP)). Není pak lepší nechat jen pár threadu (dva třeba) a v každém z nich spracovávat jen některé klienty (sudé jedno vlákno a liché druhé vlákno)?
Softwarová simulace druhého jádra
Datum: 23.5.2008 14:24
Autor: neregistrovaný (194.228.18.137)
Hodnocení autora: není
Příspěvků: 0
Já bych se přidal také s jedním dotazem. V práci máme jednojádrová pentia s tím, že mají softwarovou simulaci druhého jádra (teď si za boha nemůžu vzpomenout jak se to jmenuje, ale předtím než se masově rozšířilo používání dvoujáder do osobních PC, používalo se to docela často). Je mi jasné že pokud má procesor jedno jádro, nemůže zpracovávat současně více úkolů. Ale zajímalo by mě, zda se tato simulace druhého jádra projeví nějákým zásadnějším způsobem do chodu vícevláknové aplikace. (předem podotýkám že mi není moc jasné jak tato simulace pracuje)
Mutex? synchronizace
Datum: 25.5.2008 1:02
Autor: neregistrovaný (90.183.62.110)
Hodnocení autora: není
Příspěvků: 0
Uloha
Mame dva nezavisle programy
Program 1 =P1
Program 2 =P2
DataPro prenos mezi nezavislymi programy =DP
Vytvorim DP v (metodu navrhnete napr. glogalni pamet
mozna je i neco jineho)
V P1 zamknu pristup k DP P2
Naplnim DP programem P1 (P2 ceka nebo cyklicky testuje zamek)
V P1 odemknu pristup k DP a P2 zamkne pristup k DP P1
Tet muzu v P2 delat v DP co chci ,cist, zapsat jine data
(P1 pokud mezitim pozada o pristup chova se stejne jako P2,
ktery cekal nebo testoval zamek)
V P2 odemknu pristup k DP
V P1 zamknu pristup k DP P2
A tak dale . ...
Brzo zjstite ze cast P1 a P2 musi bezet v samostatnem vlakne aby takto programy komunikovaly s predavanim dat.
Na takovy typ ulohy ve vlaknech by me zajimala cilova ukazka.
S pozdravem Bob
Re: Mutex? synchronizace
Datum: 25.5.2008 10:59
Autor: neregistrovaný (90.183.62.110)
Hodnocení autora: není
Příspěvků: 0
Trochu to upresnim.
1)Cil 1 navrnout DP (muzeme tak prenaset data mezi Px = P1 ,P2 ,... kde x=<1,x>
Pritom obecne Px muze byt jak ve VB.net tak C++, VB6 a podobne .
Pro priklad je vhodne zustat u vb.net)
DP bych ocekaval v RAM kvuli rychlosti prenosu,
pricemz se musi navrhnout zpusob jak programy Px nezavisle zjisti ,
ze DP existuje a pokud neexistuje tak ho prvni kery to stihne zalozi ostatni se jen
podileji
(nechci to presneji konkretizovat , protoze je mozne ,ze existuje
i reseni o kterem jsem netusil, abych Vas neovlivnil pri reseni.
Bezne by kazdemu programu mela stacit informace
o nazvu oblasti s jejiz pomoci zjisti pointer odkud muze manipulovat s daty.
Pokud jde o virtualni pamet pak kazdy z Px muze mit jiny pointer a presto ve vysledku smeruje do DP
Dale by mel vedet jaka je velikost oblasti DP v bytech
Dale by z nazvu zamku mel aktivovat objekt ktery zamek zajisti.)
2)V case prenosu ma jen jediny program pravo manipulovat s DP ostatni Px cekaji.
Co se tyka ukazky tak to zjednodusim
P1 bezny programek s oknem Textbox 'povoleno multiline
a tlacitkem Start s funkci prenes data
a tlacitkem Start1 s funkci vygeneruj , zobraz a prenes data vlaknem
a checkboxem ktery v pripade zatrzeni generuje vygeneruje , zobrazi a prenese data vlaknem v nejake frekvenci cyklu
data pro prenos
dim T() as date 'Je rozumne prenaset t v ticks t(0).ticks - delka 8 byte
'z ticku zpet t(0)=new date(ticky)
dim S() as string 'pozor na stringy v cili je jen pointer do pameti kde je odkaz dale
dim D() as double 'but to prenest jako bstring (pak pointer
dim L() as long 'ukazuje na data , pointer-4 ukazuje na 4byte ktere obsahuji delku )
dim I() as integer
dim B() as byte
dim Citac as long
sub init
dim N as integer=5
redim T(N)
redim S(N)
redim D(N)
redim L(N)
redim I(N)
redim B(N)
call Generuj
Call Zobraz
end sub
sub Generuj
'nejaka fce ktera naplni nahodne vsechna pole
'v praktickem pouziti to muzou byt data, ktere chceme z ruznych duvodu prenes do uplne
'jineho programu v nasem pripade pro P2
Citac=Citac+1
end sub
Sub Zobraz
'nejaka fce ktera zobrazi vsechny pole + citac v Textbox
end sub
spustim program po inicializaci programove nebo rucne v P1 vygeneruji pole+citac, zobrazim
a vytvorim vlakno ktere zajisti prenos do DP s ochranou zamku.
navrat z vlakna se da detekovat a zobrazit ze vlakno probehlo a s jakym uspechem
(je vice metod jak to zajistit callback si nechte radeji na pozdeji)
Program P2 prijemce
Na formulari stejne TextBox okno jako v P1
Spustim program
zalozim
dim Mcitac as long =0
zalozim vlakno ktere pocka na data v DP pokud
citac ve clakne <> Mcitac =dorazily nove data
data predam do bezne casti a indikuji ,ze data jsou nove k dispozici
(predani dat pro hlavni cast musim udelat tak ,aby nekolidovaly(taky drobny zamecek))
Mcitac= citac ve clakne
vlakno se vraci na zacatek, aby moho precist nove data z DP
hlavni cast
jsou nove data - ano - poznac ze prave ctu (zamecek) zobrazim data v TextBox odemknu zamecek
(pro jednoduchost tam dejme timer na rozpoznani proporku novych dat 100 ms)
Snad je to jednoduche pro priklad.
S pozdravem Bob
Re: Mutex? synchronizace
Datum: 25.5.2008 14:36
Autor: neregistrovaný (90.183.62.110)
Hodnocení autora: není
Příspěvků: 0
Pochopil jste to velmi dobre. :)
Vb.net s pointery maka velmi dobre,
i s pametovym prostorem - jen to neni pekne zverejnene.
Protoze je to docela prakticke mezi programy si predavat data
myslel jsem, ze by to byla velmi pekne ukazka.
Je mi jasne ze je to vyzva. Vb.net toho umi hodne.
Je to na Vas ta vyzva oslovila.
Podobny sok jsem zazil ,kdyz jsem zjistil, ze se ve VB6 da
programovat a spustit aplikace psana ve zdrojovem kodu assembleru (nekdy se to muze hodit).
Pohraji si s tim zkusim to prevest do vb.netu
Pozn.
1)podivejte se na typ IntPtr. (umi vb.net pracovat s pointery)
2)drobny priklad
pridejte si do programu:
Imports System.Runtime.InteropServices
Dim BPole(100) As Double
Dim BM as IntPtr 'Pointer kam zapsat data
Marshal.Copy(BM, BPole, 0, BPole.Length)
zkopiruje Bpole od indexu 0 na misto v pameti od adresy BM
o delce BPole.Length*8 [Byte]; delka 1 [double]=8 [byte]
3)v Class Marshal muzete alokovat i prostor pameti a ten pouzit.
4)Popripade pouzit jak rikate API pro Kanal v pameti pres mapovani v pameti.
Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Integer, ByVal lpFileMappigAttributes As IntPtr, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer
a pouzit Mutex pro informaci o zamku
Dim MMutex As System.Threading.Mutex
Dim KanalJmeno As String ="JmenoMutexu"
MMutex = New System.Threading.Mutex(False, KanalJmeno, False)
a dotazovat se pres zamky
Dim B1 As Boolean
Dim KanalmillisecondsTimeout As Integer = 2000
B1 = MMutex.WaitOne(KanalmillisecondsTimeout, False)
If B1 = True Then
'zamkl jsem DP muzu snim pracovat
'pracuji
Call MMutex.ReleaseMutex() 'Uvolneni zamku
Else
'behem 2 sekund jsem se k DP nedostal
End If
S pozdravem Bob
pak muzete cist
Re: Mutex? synchronizace
Datum: 25.5.2008 17:26
Autor: neregistrovaný (90.183.62.110)
Hodnocení autora: není
Příspěvků: 0
V prikladu BM mela byt cilova adresa.
Prominte dal jsem tam opacny smer: spravne Bpole do pameti BM
Marshal.Copy(BPole, 0, BM, BPole.Length)
'Aritmeticke operace
dim B1 as intptr
dim B2 as intptr
dim x as integer
'pointer+x
B2=new IntPtr(B1.ToInt32 + x) ' tuto blninu jsem hledal malem rok
nastudujte Api:
(ps:ve vb.net 2008 by mely byt i jine moznosti - tesil jsem se ze je znate :( )
pointer ktery Vas zajima:
New IntPtr(MMapAdr)
Private Declare Function OpenFileMapping Lib "kernel32" Alias "OpenFileMappingA" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal lpName As String) As Integer
Private Declare Function MapViewOfFile Lib "kernel32" Alias "MapViewOfFile" (ByVal hFileMappingObject As Integer, ByVal dwDesiredAccess As Integer, ByVal dwFileOffsetHigh As Integer, ByVal dwFileOffsetLow As Integer, ByVal dwNumberOfBytesToMap As Integer) As Integer
MmapHandle = OpenFileMapping(Win32FileMapAccess.FILE_MAP_ALL_ACCESS, 0, MName)
MMapAdr = MapViewOfFile(MmapHandle, Win32FileMapAccess.FILE_MAP_WRITE, 0, 0, 0)
S pozdravem Bob
Re: Mutex? synchronizace
Datum: 25.5.2008 17:40
Autor: neregistrovaný (90.183.62.110)
Hodnocení autora: není
Příspěvků: 0
Jeste upresneni:
Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Integer, ByVal lpFileMappigAttributes As IntPtr, ByVal flProtect As Integer, ByVal dwMaximumSizeHigh As Integer, ByVal dwMaximumSizeLow As Integer, ByVal lpName As String) As Integer
' dwMaximumSizeHigh =0 'Hornich 32 bitu MaximumSizeHight; =0 pro file <= 4 Gbyte
' dwMaximumSizeLow =MSize 'Dolnich 32 bitu MaximumSizeHight
MmapHandle = OpenFileMapping(Win32FileMapAccess.FILE_MAP_ALL_ACCESS, 0, MName)
If MmapHandle <= 0 Then
MmapHandle = CreateFileMapping(0, IntPtr.Zero, PAGE_READWRITE, B2H32, B1L32, MName)
End If
S pozdravem Bob
Re: Kdy bude dalsí díl???
Datum: 9.2.2009 11:33
Autor: neregistrovaný (213.68.144.90)
Hodnocení autora: není
Příspěvků: 0
Už se opravdu nemůžu dočkat dalšího dílu.
Detail
Datum: 19.3.2009 7:38
Autor: neregistrovaný (62.84.154.56)
Hodnocení autora: není
Příspěvků: 0
Nešlo by prosím v článku opravit okno kódu, aby se dalo snáze přečíst.
Je to sice nedůležitý detail, ale jak je to jednobarevné, tak se v tom špatně orientuji :)
Děkuji
Re: Detail
Datum: 20.3.2009 15:35
Autor: neregistrovaný (87.197.143.238)
Hodnocení autora: není
Příspěvků: 0
Radšej by som sa dočkal druhého dielu .......
Re: Detail
Datum: 14.12.2011 23:32
Autor: neregistrovaný (78.45.213.196)
Hodnocení autora: není
Příspěvků: 0
Stačí si zkopírovat do Visual Studia...
Mýty okolo vláken
Datum: 2.6.2009 17:16
Autor: neregistrovaný (193.84.202.2)
Hodnocení autora: není
Příspěvků: 0
Hezký den
nejsem profesionální uživatel .net či VB, ale chtěl bych uvést několik skutečností, které souvisí s aplikacemi, která používají vlákna. Čerpám z vlastností thread implementovaných na systémech Unixu, a předpokládám, že MS nevymyslel zcela něco nového a ve vlastním helpu VB MS nic bližšího neuvádí.
1. podle mne panuje omyl, že když vytvořím např. aplikaci pomocí vláken, která má např. uhodnout heslo, dojde ke brutálnímu zkrácení času. Omyl, neboť vlákna jsou OS UNIX a předpokládám, že tak funguje WIN, udržována pod procesem, který je vytvořil a tomuto procesu určuje strojový čas preemptivní multitasking, tzn. výsledný čas ovlivňuje to, kolik strojového času dostane rodičovský proces a tím pádem i jednotlivá vlákna. (A je-li multitasking chytře vyřešen, tak proces s vlákny dostává tolik strojového času, kolik mu může systém přidělit.) Dále vlákno tím, že je udržováno pod procesem, nemůže být přeneseno na více než jedno fyzické jádro procesoru. Pokud to vím, tak možnost přenosu vlákna mezi fyzickým jádry procesoru žádný OS nemá, neboť je to velice složitá věc. Pro urychlení práce na více jádrech slouží zcela jiné nástroje, pracující s procesy, jako je např. MPI - Message Passing Interface a to není součásti VB.
2. pravý účel vláken lze právě spatřit ve všech aplikacích typu klient - server, kdy na serveru obsluhují klienty právě samostatná vlákna. Proč? Nutno si uvědomit, že ať používám TCP či UDP a ať používám nějaký systém kontroly přenosu, pošlu-li data klientovi, musím čekat několik ms na jeho odpověď (i v TCP, kde se o přenos starají nižší vrstvy OSI, jsou mezi jednotlivými pakety na straně odesílatele pauzy). No a tu čekací dobu mohu použít pro práci s jiným klientem. Taky jak zaznělo v jednom příspěvku, je možno vlákna využít i u některých aplikací, které mohou využívat vlákna pro čtení a zápis souborů na pozadí, v době kdy uživatel s aplikací pracuje (např. textový procesor, prakticky stále hnípe, neboť bych chtěl několi vidět, jak stále buší do klávesnice rychlostí několik kilo znaků/s).
Nemám-li pravdu dle bodu č. 1. tak musím smeknout před MS.
Jarda
Priklad do C#
Datum: 6.8.2011 8:50
Autor: neregistrovaný (178.40.24.252)
Hodnocení autora: není
Příspěvků: 0
Zdravím :)
Mám možno trochu hlúpu prosbu (som na webe VB), ale nemohli by ste uviesť uvedený príklad aj v jazyku C#?
Dik ;)
Re: Priklad do C#
Datum: 7.10.2011 7:50
Autor: neregistrovaný (213.226.251.213)
Hodnocení autora: není
Příspěvků: 0
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Threading;
static class Module1
{
//Pole pro naplnění náhodnými čísly (sdílená data)
private static int[] numbers = new int[10000000];
public static void Main()
{
//Nastaví název hlavního vlákna programu
//(potom je přehledně vidět v seznamu vláken při ladění)
Thread.CurrentThread.Name = "Main";
//Naplnit celé pole náhodnými čísly jen pomocí hlavního vlákna
ProcessNumbers(new int[] {
0,
9999999
});
//Vytvoření dvou vláken které budou provádět metodu ProcessNumbers
//(každé vlákno nezávisle na sobě)
Thread numberProcessor1 = new Thread(ProcessNumbers);
Thread numberProcessor2 = new Thread(ProcessNumbers);
numberProcessor1.Name = "numberProcessor1";
numberProcessor2.Name = "numberProcessor2";
//Spuštění obou vláken s parametrem (počátek a konec plnění pole)
numberProcessor1.Start(new int[] {
0,
4999999
});
numberProcessor2.Start(new int[] {
5000000,
9999999
});
Console.ReadKey();
}
//Metoda pro naplnění pole náhodnými čísly
//(musí odpovídat delegátu System.Threading.ThreadStart nebo
//System.Threading.ParameterizedThreadStart)
private static void ProcessNumbers(object obj)
{
System.DateTime t0 = System.DateTime.Now;
//Přetypování z objektu na pole dvou čísel
//(počátek a konec plnění pole)
int[] indexes = (int[])obj;
Random randomizer = new Random();
for (int index = indexes[0]; index <= indexes[1]; index++) {
numbers[index] = randomizer.Next(int.MinValue, int.MaxValue);
}
Console.WriteLine(string.Format("{0}: {1:N0} ms", Thread.CurrentThread.Name, System.DateTime.Now.Subtract(t0).TotalMilliseconds));
}
}