Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

C# exceptions in een thread

Pagina: 1
Acties:

  • ? ?
  • Registratie: Mei 2007
  • Niet online
Als ik een werkje wil executen, dan gebruik ik een Thread.
Sinds 4.0 kun je ook Tasks gebruiken, maar ik wil het nu op Threads houden.

Met een backgroundworker heb ik eigenlijk nog niet veel gewerkt en een Thread is gewoon makkelijk.
Voordeel: de core wordt niet aan 100% belast tijdens de berekeningen.

Alleen werkt het opvangen van een exception niet echt zoals het hoort.
code:
1
2
3
4
5
6
7
8
9
10
                try
                {
                    Thread thd = new Thread(new ThreadStart(worker.Run));
                    thd.Start();
                    thd.Join();
                }
                catch (Exception ex)
                {
                    //doe iets met de exception, meestal gewoon rapporteren dat de berekening niet lukt
                }

Deze catch gaat echter niet de exceptions vangen in de Thread...
Hoe kan ik dat best toch doen?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Randmr schreef op woensdag 23 oktober 2013 @ 09:26:
Voordeel: de core wordt niet aan 100% belast tijdens de berekeningen.
Waarom niet? Je core kan prima "100%" belast worden, alleen heb je een UI-thread en/of andere threads die ook aandacht krijgen.
Een backgroundworker / Task gebruiken. Je zegt 't zelf al. En anders je google-fu gebruiken en zoiets eens bekijken.

[ Voor 12% gewijzigd door RobIII op 23-10-2013 09:56 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • ? ?
  • Registratie: Mei 2007
  • Niet online
Op een (virtuele) server met 1 core is 100% belasting niet plezant. (Windows draait dan voor geen meter meer)
Het gaat mij vooral om dat voordeel (van een thread). Terwijl een backgroundworker geloof ik wel eens last heeft van hoge cpu belasting zo lees ik.

[ Voor 8% gewijzigd door ? ? op 23-10-2013 09:59 ]


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Whut? Of je nou je main thread 100% belast of een aparte thread: het werk zal toch verzet moeten worden en 't is niet alsof een losse thread je "100%" belasting magisch oplost. En een BGW heeft echt niet noemenswaardig (if any) meer/minder verschil in "belasting" dan eender welke oplossing.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • ? ?
  • Registratie: Mei 2007
  • Niet online
(virtual) Server: W2003 één core

code:
1
2
3
4
5
6
7
8
    class Program
    {
        for(int i = 0;i<10000000;i++)
        {
            someCalculations(); //duurt 5 minuten
            someAsyncCalculations(); //duurt 1 minuut
        }
    }


=> dit gaat de cpu (en enige core) voor 100% belasten en dan kan je niks meer doen, zelfs de startknop is dan lastig om te openen.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    class Program
    {
        Worker worker = new Worker();
        Thread thd = new Thread(new ThreadStart(worker.Run));
        thd.Start();
        thd.Join();
    }

    class Worker
    {
        public void Run()
        {
            someCalculations(); //duurt 5 minuten
            someAsyncCalculations(); //duurt 1 minuut
        }
    }


=> dit belast de cpu zeer laag, je kan windows nog prima blijven gebruiken :P

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 13:43
Ik weet niet wat someAsyncCalculations doet, maar als het doet wat ik vermoed en je start het in de ene testcase maar 1x en in de andere 10000000x, tsja..

Roomba E5 te koop


  • Merethil
  • Registratie: December 2008
  • Laatst online: 08:50
Dit begrijp ik niet helemaal. Hoe zou de main-thread je CPU in één keer zo zwaar belasten terwijl een aparte thread die op exact dezelfde core draait dit totaal niet doet?
Is het allebei wel even snel? Heb je het allebei wel op dezelfde manier draaien?

Kijk ook naar was sig69 zegt, was ook het eerste wat mij opviel. Vooral omdat je het hebt over async en dus daar weer aparte threads (lijkt me?) in hebt lopen...

Edit: Het enige wat ik zou kunnen bedenken is dat omdat je een virtuele server draait je het op de één of andere manier voor elkaar krijgt dat de thread afgehandeld wordt door de andere cores die niet zijn toegewezen voor deze VM, waar Windows niet op draait, maar da's bijna witchcraft :P

[ Voor 25% gewijzigd door Merethil op 23-10-2013 10:18 ]


  • ? ?
  • Registratie: Mei 2007
  • Niet online
Het is maar een voorbeeldje, ik gebruik deze constructie eigenlijk voor zowat al mijn processen die volledig autonoom (zonder user input) moeten lopen. (misschien ben ik gewoon al altijd 'verkeerd' bezig :P)

Ander voorbeeld: er moeten gegevens gedownload worden van een ftp, deze moeten verwerkt worden (aanpassing van formaat) en dan moet dit in een database inserted worden.

Dat downloaden van FTP kan een minuutje duren, soms meer, soms minder, als het bestand 10.000 lijnen heeft die ingelezen moeten worden om iets te veranderen duurt dat ook en daarna moeten er inserts gedaan worden in een database.

=> als ik dat gewoon in class Program { } gooi als statements onder elkaar dan hangt elke server met één core (toch??? zeker bij het inlezen van 10.000 lijntjes tekst en ik kan toch moeilijk een thread.sleep gebruiken bij elke iteratie).

=> veel exception handling is er niet nodig: ofwel lukt het ofwel niet (en dan wordt dit gelogd, volgende keer beter)

  • Merethil
  • Registratie: December 2008
  • Laatst online: 08:50
Volgens mij hangt dan niet de server op 100% te hangen, maar het programma z'n UI-Thread zal wel hangen tot 'ie klaar is met verwerken.
Dat de UI-thread 100% van je CPU gebruikt is netjes, dan is het programma snel klaar, maar hoe kan het in hemelsnaam zijn dat als je in een andere thread (Die op exact dezelfde core van je CPU draait) de bewerkingen doet opeens je CPU niet naar 100% schiet?

Merk je geen verschil in snelheid? Enige optie die ik heb is dat er gebottlenecked wordt hoeveel CPU-power er gebruikt mag worden als je niet de main-thread (UI-thread) gebruikt om de verwerking te doen, maar dat lijkt me erg onwaarschijnlijk...

Edit: Het afhandelen van je exceptions doe je trouwens toch gewoon in de functie zelf? Zodat je het altijd afhandelt op dezelfde manier, of je nou een workerthread of je UI-thread hem laat afhandelen? Zoals je het nu hebt staan in je voorbeeld in je Topic Start vang je alle Exceptions van het Thread object zelf ook af, da's ook handig. Maar alles wat 'ie uitvoert moet gewoon in de uitvoering zelf afgehandeld worden imo.

[ Voor 25% gewijzigd door Merethil op 23-10-2013 10:32 ]


  • Mint
  • Registratie: Mei 2005
  • Laatst online: 20-11 22:35
Randmr schreef op woensdag 23 oktober 2013 @ 10:24:
Het is maar een voorbeeldje, ik gebruik deze constructie eigenlijk voor zowat al mijn processen die volledig autonoom (zonder user input) moeten lopen. (misschien ben ik gewoon al altijd 'verkeerd' bezig :P)

Ander voorbeeld: er moeten gegevens gedownload worden van een ftp, deze moeten verwerkt worden (aanpassing van formaat) en dan moet dit in een database inserted worden.

Dat downloaden van FTP kan een minuutje duren, soms meer, soms minder, als het bestand 10.000 lijnen heeft die ingelezen moeten worden om iets te veranderen duurt dat ook en daarna moeten er inserts gedaan worden in een database.

=> als ik dat gewoon in class Program { } gooi als statements onder elkaar dan hangt elke server met één core (toch??? zeker bij het inlezen van 10.000 lijntjes tekst en ik kan toch moeilijk een thread.sleep gebruiken bij elke iteratie).

=> veel exception handling is er niet nodig: ofwel lukt het ofwel niet (en dan wordt dit gelogd, volgende keer beter)
Elke server met één core hangt dan, ongeacht of je een aparte thread gebruikt. Wat RobIII al aangeeft, het werk zal toch verzet moeten worden. Bij het gebruik van een BackgroundWorker zal je UI thread niet hangen, omdat deze niet hoeft te wachten totdat je bewerkingen zijn uitgevoerd. Het CPU gebruik zal niet anders zijn, omdat je dus hetzelfde werk zal moeten doen. Of het nou in een main method staat, of in een apare thread, dat maakt niet uit.

  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Andere posters hebben inderdaad gelijk dat de load niet ineens magisch minder word.

Het enige punt waarop je kan voorkomen dat constant alle CPU tijd naar je applicatie gaat is op het moment dat je zit te wachten op dingen die je (main) thread blocken (bijvoorbeeld methods die blocken totdat er een input buffer gevuld is). Dat is een moment waarop je richting Windows kan zeggen: "Ik zit toch maar te wachten, dus doe jij je ding maar even". Je kan hiervoor een simpele sleep gebruiken, maar je kan beter kijken naar een oplossing die meer gericht is op jouw specifieke scenario. Verdiep je bijvoorbeeld ook eens in diverse async patterns.

Dit is een kwestie van een andere aanpak, je applicatie word er niet sneller van qua doorlooptijd, maar je smeert de load meer uit. (kan het niet onderbouwen, maar kan me voorstellen dat de doorlooptijd zelfs langer word door de ruimte die je inbouwt om even van task te switchen etc).

[ Voor 20% gewijzigd door Laurens-R op 23-10-2013 11:05 ]


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
Randmr schreef op woensdag 23 oktober 2013 @ 09:26:

...

Alleen werkt het opvangen van een exception niet echt zoals het hoort.
code:
1
2
3
4
5
6
7
8
9
10
                try
                {
                    Thread thd = new Thread(new ThreadStart(worker.Run));
                    thd.Start();
                    thd.Join();
                }
                catch (Exception ex)
                {
                    //doe iets met de exception, meestal gewoon rapporteren dat de berekening niet lukt
                }

Deze catch gaat echter niet de exceptions vangen in de Thread...
Hoe kan ik dat best toch doen?
Met je eigen tread zal je de exceptie in de thread zelf moeten afvangen, en deze afhandelen of de thread stoppen en de exceptie op een of andere manier naar je main thread sturen (als result oid).

Een backgroundworker zal ook in een aparte thread lopen, deze heeft alleen wat handige events om de progress bij te houden, ook zullen excepties hier in de AsyncCompletedEventArgs terecht komen.
http://msdn.microsoft.com...kgroundworker.dowork.aspx
http://msdn.microsoft.com...args.error(v=vs.110).aspx

Je voorbeeld met FTP lijkt me ideaal om asynchroon te doen omdat het downloaden 'langzame' IO is waarbij de CPU niks te doen heeft. Zodra een file binnen is kan je deze dan (Async als je meerdere cores hebt) processen. Het inserten in de DB lijkt me iets wat je in een single thread doet. Een database lijkt me 'blijer' met sequentiële inserts dan met parallelle.

[ Voor 12% gewijzigd door epic007 op 23-10-2013 11:15 ]


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Randmr schreef op woensdag 23 oktober 2013 @ 09:26:
Als ik een werkje wil executen, dan gebruik ik een Thread.
Sinds 4.0 kun je ook Tasks gebruiken, maar ik wil het nu op Threads houden.

Met een backgroundworker heb ik eigenlijk nog niet veel gewerkt en een Thread is gewoon makkelijk.
Er is maar één ding makkelijk aan System.Threading.Thread en dat is om ze fout te gebruiken. Tasks kosten maar een klein beetje meer werk om juist op te zetten dan het kost om snel en fout rauwe threads op te zetten. Dat kleine beetje extra werk forceert jou om je code op zo'n manier in elkaar te zetten dat je niet met nog een paar dozijn verborgen gebreken blijft zitten die je over de lange linie gemeten wellicht een paar honderd keer zoveel tijd kosten dan het verschil tussen de initiële extra investering om met Tasks te werken...

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
De meeste mensen die zelf met threads gaan kloten doen het fout.
Zeker wat ik hier al zie, de TS gebruikt
C#:
1
Thread thd = new Thread(new ThreadStart(worker.Run));

Weet je wel hoe verschrikkelijk zwaar het is om een nieuwe thread te maken? new Thead is gewoon not-done. en zeker niet in een loop. (dus vaak)
Als je zelf threads wilt gebruiken heb je zoiets als ene ThreadPool.

Maar zoals R4gnax al aangeeft. Parallel tasks zijn veel beter, en een stuk simpeler om te gebruiken.
Helemaal als je weinig controlle op je thread hoeft te hebben (als je hem niet wilt aborten van buitenaf enzo)
check dit voorbeeld:
Parallel.ForEach(items, item =>
{
//work with item
});
edit:
kijk nou eens wat ik vind:
How to: Handle Exceptions in Parallel Loops

[ Voor 40% gewijzigd door BasieP op 23-10-2013 23:04 ]

This message was sent on 100% recyclable electrons.


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
BasieP schreef op woensdag 23 oktober 2013 @ 22:40:
Maar zoals R4gnax al aangeeft. Parallel tasks zijn veel beter, en een stuk simpeler om te gebruiken.
Helemaal als je weinig controlle op je thread hoeft te hebben (als je hem niet wilt aborten van buitenaf enzo)
Threads wil je sowieso nooit aborten en zeker niet van buiten af.
Check o.a. How To Stop a Thread in .NET (and Why Thread.Abort is Evil) van Phil Haack.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13:12
BasieP schreef op woensdag 23 oktober 2013 @ 22:40:
C#:
1
Thread thd = new Thread(new ThreadStart(worker.Run));

Weet je wel hoe verschrikkelijk zwaar het is om een nieuwe thread te maken? new Thead is gewoon not-done.
Owh common, we maakten op onze single core Pentium III's al threads aan die met de nodige zorg prima hun werk deden ( granted, niet met .NET ) en nu ga je ons wijsmaken dat het aanmaken van een thread op de quad+ core bakken die nu iedereen heeft "zwaar" is?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Een thread aanmaken is zwaar. Maar niet zo zwaar als hij zegt.. Mijn project spawnt 7 threads on startup achter elkaar, er zit 5.1ms tussen het begin van de lifeline van de eerste thread en de laatste thread. Dat is met C++ std::thread op een windows bak.

Als 100 threads per seconde spawnt wordt het misschien een probleem..

[ Voor 4% gewijzigd door Verwijderd op 24-10-2013 02:05 ]


  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Als je dan toch wil overwegen om een Threadpool te gebruiken:

MSDN: The Managed Thread Pool

Daar staan ook gelijk een aantal overwegingen beschreven. Vanaf .net 4 trouwens gewoon de Task class gebruiken, deze maakt automatisch gebruik van een ThreadPools e.a. optimalizaties.

  • Lethalis
  • Registratie: April 2002
  • Niet online
Ik werk altijd met een BackgroundWorker. Exceptions afvangen doe ik in de threads zelf. Eventuele foutmeldingen geef ik dan via een stateobject terug aan de main thread met de ReportProgress functie (kun je ook een object aan meegeven).

Ask yourself if you are happy and then you cease to be.


  • Lethalis
  • Registratie: April 2002
  • Niet online
Het is 2013, het jaar waarin we - helaas - nog genoeg klanten hebben met Windows XP (waar .NET 4.5 zeker niet op geinstalleerd is).

Ask yourself if you are happy and then you cease to be.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Lethalis schreef op donderdag 24 oktober 2013 @ 13:30:
[...]

Het is 2013, het jaar waarin we - helaas - nog genoeg klanten hebben met Windows XP (waar .NET 4.5 zeker niet op geinstalleerd is).
Ook gewoon in .NET 4.0 aanwezig ( MSDN: Task Parallelism (Task Parallel Library) ).

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Lethalis
  • Registratie: April 2002
  • Niet online
Ok, mea culpa :D

Helaas heb ik ook nog een klant zonder .NET 4 waar ik zelf niets aan de server mag doen, dus dan houdt het wel op.

Over het algemeen wacht ik altijd met het toepassen van de nieuwste technieken, omdat ik weet dat het vaak bij de klant tot problemen kan leiden. Vaak omdat ze daar dan niet de nieuwste updates hebben geinstalleerd en dat ook weigeren te doen (kritische servers, moeten vooral blijven draaien, etc), maar dus ook omdat er klanten zijn met oeroude PC's.

Voor sommige projecten werk ik nog met Visual Studio 2008 :X

Aan de andere kant begrijp ik ook wel dat ze er niet op zitten te wachten om op zondag te werken alleen omdat ik een update wil :D

Ask yourself if you are happy and then you cease to be.


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Tja het is helaas een feit dat er nog veel bedrijven op Windows XP draaien, maar die lopen wel erg achter de feiten aan. Ik mag hopen dat er binnenkort toch eens wat meer beweging gaat komen aangezien in april ook de extended support op Windows XP afloopt.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13:12
Verwijderd schreef op donderdag 24 oktober 2013 @ 02:05:
Een thread aanmaken is zwaar. Maar niet zo zwaar als hij zegt.. Mijn project spawnt 7 threads on startup achter elkaar, er zit 5.1ms tussen het begin van de lifeline van de eerste thread en de laatste thread. Dat is met C++ std::thread op een windows bak.

Als 100 threads per seconde spawnt wordt het misschien een probleem..
Nja het is maar wat je zwaar noemt, als je voor .NET kiest ga je imho voornamelijk voor "makkelijk" en niet voor het laatste greintje performance.

Anyways, als je zelf een thread maakt wordt je in mijn MSDN nog altijd niet zo afgefakkeld als hier het geval lijkt te zijn.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • sig69
  • Registratie: Mei 2002
  • Laatst online: 13:43
Nou ja zwaar... Ik denk dat relatief zwaar bedoeld wordt. Maar goed, als we dan toch msdn gaan refereren:
Starting with the .NET Framework 4, multithreaded programming is greatly simplified with the System.Threading.Tasks.Parallel and System.Threading.Tasks.Task classes, Parallel LINQ (PLINQ), new concurrent collection classes in the System.Collections.Concurrent namespace, and a new programming model that is based on the concept of tasks rather than threads. For more information, see Parallel Programming in the .NET Framework.
MSDN: Managed Threading

Roomba E5 te koop


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
farlane schreef op donderdag 24 oktober 2013 @ 18:34:
Nja het is maar wat je zwaar noemt, als je voor .NET kiest ga je imho voornamelijk voor "makkelijk" en niet voor het laatste greintje performance.
Dan heb je overduidelijk toch geen benul van scaling zoals dat speelt bij grote websites of web applicaties.
Daar zul je behoorlijk snel merken dat efficient met threads omgaan niks te maken heeft met 'het laatste greintje'...
farlane schreef op donderdag 24 oktober 2013 @ 18:34:
[...]
Anyways, als je zelf een thread maakt wordt je in mijn MSDN nog altijd niet zo afgefakkeld als hier het geval lijkt te zijn.
Voor de volledigheid wil je misschien ook even linken naar de voorpagina van de 'Managed Threading' sectie waarin je nu aan het deep-linken bent, zoals sig69 ook al aangaf:
Het 'Managed Threading' topic op MSDN schrijft:
Starting with the .NET Framework 4, multithreaded programming is greatly simplified with the System.Threading.Tasks.Parallel and System.Threading.Tasks.Task classes, Parallel LINQ (PLINQ), new concurrent collection classes in the System.Collections.Concurrent namespace, and a new programming model that is based on the concept of tasks rather than threads. For more information, see Parallel Programming in the .NET Framework.
Of nog een tikkie hoger in de document hierarchie:
Het 'Parallel Processing and Concurrency in the .NET Framework' topic op MSDN schrijft::
Asynchronous Programming Patterns
Provides a brief overview of the three asynchronous programming patterns supported in the .NET Framework:
  • Asynchronous Programming Model (APM) (legacy)
  • Event-based Asynchronous Pattern (EAP) (legacy)
  • Task-based Asynchronous Pattern (TAP) (recommended for new development)
Dus Microsoft beschouwt het rauw aanspraak maken op threads en threadpools wel degelijk als een legacy aanpak en probeert je aan te sturen Tasks te gebruiken.

[ Voor 11% gewijzigd door R4gnax op 24-10-2013 20:19 ]


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
BasieP schreef op woensdag 23 oktober 2013 @ 22:40:
Weet je wel hoe verschrikkelijk zwaar het is om een nieuwe thread te maken? new Thead is gewoon not-done.
Wat een onzin. Een thread kost vooral veel geheugen (zo'n 2MB geloof ik) maar afgezien daarvan is het niks bijzonders. En als je tig tasks parallel wilt hebben lopen moeten daar ook evenveel threads voor aangemaakt worden (tenzij je async bezig bent). Tasks zijn vooral een handigheidje voor programmeurs, weinig meer. En geen enkele goeie programmeur heeft moeite met threads, dat is iets wat je gewoon moet kunnen.
R4gnax schreef op donderdag 24 oktober 2013 @ 20:15:

Dus Microsoft beschouwt het rauw aanspraak maken op threads en threadpools wel degelijk als een legacy aanpak en probeert je aan te sturen Tasks te gebruiken.
Threads hebben vooral een memory overhead, voor taken die vooral veel blocking IO doen is async meer geschikt. Bij taken die vooral complexe berekeningen doen, levert async je weer relatief weinig op. Best tool for the job dus.

[ Voor 28% gewijzigd door Hydra op 24-10-2013 20:22 ]

https://niels.nu


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13:12
R4gnax schreef op donderdag 24 oktober 2013 @ 20:15:
[...]
Dan heb je overduidelijk toch geen benul van scaling zoals dat speelt bij grote websites of web applicaties.
Daar zul je behoorlijk snel merken dat efficient met threads omgaan niks te maken heeft met 'het laatste greintje'...
Het ging hier over de opstarttijd van een thread, die i.h.a. miniscuul is vergelelen met zijn totale levensloop. Er werd ook al aangegeven dat het waarschijnlijk minder handig is om 100 threads per seconde the spawnen.

Er is overigens weinig noodzaak om het meteen op de man te gaan spelen op het moment dat ik "performance" in combinatie met ".NET" gebruik.
Voor de volledigheid wil je misschien ook even linken naar de voorpagina van de 'Managed Threading' sectie waarin je nu aan het deep-linken bent, zoals sig69 ook al aangaf:

Dus Microsoft beschouwt het rauw aanspraak maken op threads en threadpools wel degelijk als een legacy aanpak en probeert je aan te sturen Tasks te gebruiken.
Ook allemaal erg interessant ( over de async methoden ging het niet trouwens, maar dat terzijde ) maar het neemt niet weg dat er in de documentatie die ik link niet vermeld wordt dat het niet meer gebruikt mag worden, of dat je in de hel komt zoals sommigen je hier willen doen geloven.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • sig69
  • Registratie: Mei 2002
  • Laatst online: 13:43
farlane schreef op donderdag 24 oktober 2013 @ 21:44:
[...]

Ook allemaal erg interessant ( over de async methoden ging het niet trouwens, maar dat terzijde ) maar het neemt niet weg dat er in de documentatie die ik link niet vermeld wordt dat het niet meer gebruikt mag worden, of dat je in de hel komt zoals sommigen je hier willen doen geloven.
Dat ben ik met je eens hoor. Maar een Task zou voor de TS wel handig zijn. Ik neem aan dat hij de documentatie inmiddels ook heeft gelezen en gezien heeft dat het ding een MSDN: Task.Exception Property (System.Threading.Tasks) property heeft die precies doet wat hij wil.

Roomba E5 te koop


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
farlane schreef op donderdag 24 oktober 2013 @ 01:39:
Owh common, we maakten op onze single core Pentium III's al threads aan die met de nodige zorg prima hun werk deden ( granted, niet met .NET ) en nu ga je ons wijsmaken dat het aanmaken van een thread op de quad+ core bakken die nu iedereen heeft "zwaar" is?
Je pc heeft niet zoveel last van het draaien van threads, dat wil je gewoon, maar de code die er uitgevoerd wordt als jij in .NET zegt '... = new Thread()' is WEL lomp.

Er bestaat niet voor niets iets als een threadpool. Dat was niet omdat een ontwikkelaar dacht 'goh ik verveel me'
Hydra schreef op donderdag 24 oktober 2013 @ 20:20:
Wat een onzin. Een thread kost vooral veel geheugen (zo'n 2MB geloof ik) maar afgezien daarvan is het niks bijzonders. En als je tig tasks parallel wilt hebben lopen moeten daar ook evenveel threads voor aangemaakt worden (tenzij je async bezig bent). Tasks zijn vooral een handigheidje voor programmeurs, weinig meer. En geen enkele goeie programmeur heeft moeite met threads, dat is iets wat je gewoon moet kunnen.
Niks mis met Threads, maar wel op de manier zoals de TS het nu aanpakt:
lees: = new Thread()

Je kunt dat heel praktisch testen door binnen een loopje (laten we zeggen 1000x) een thread een simpele taak uit te laten voeren en de tijd te meten. (dus niet parallel, maar gewoon .start() en .join() achter elkaar.)
en datzelfde te doen dmv tasks (ook niet parallel)
Ga dan eens kijken hoe verschrikkelijk veel sneller de tasks zijn.

Zoiets dus:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
static void Main(string[] args)
{
    var start = DateTime.Now;

    for (int i = 0; i < 10000; i++)
    {
        Parallel.For(0, 1, x =>
        {
            threadMethod();
        });
    }

    Console.WriteLine(DateTime.Now.Subtract(start).TotalMilliseconds + "ms");

    start = DateTime.Now;

    for (int i = 0; i < 10000; i++)
    {
        var t = new Thread(new ThreadStart(threadMethod));
        t.Start();
        t.Join();
    }

    Console.WriteLine(DateTime.Now.Subtract(start).TotalMilliseconds + "ms");


    Console.ReadKey();
}

private static void threadMethod()
{
    //om maar wat te doen
    var woei = 3 + 3;  
    var waai = woei;
    woei = 3 + waai;
}

mijn output is:
32,0018ms
18671,0679ms


edit:
kleine aanpassing in de code

[ Voor 26% gewijzigd door BasieP op 24-10-2013 23:44 ]

This message was sent on 100% recyclable electrons.


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13:12
BasieP schreef op donderdag 24 oktober 2013 @ 23:34:
Je pc heeft niet zoveel last van het draaien van threads, dat wil je gewoon, maar de code die er uitgevoerd wordt als jij in .NET zegt '... = new Thread()' is WEL lomp.

Er bestaat niet voor niets iets als een threadpool. Dat was niet omdat een ontwikkelaar dacht 'goh ik verveel me'
Een threadpool is er voor om kortdurende taken in een andere thread te kunnen laten draaien, omdat daar het maken en opruimen van een Thread object onevenredig veel overhead zou veroorzaken.

Er wordt echter helemaal niet verteld hoe lang de taak in die thread duurt, voor hetzelfde geld is dat een minuut of misschien wel gedurende de looptijd van de applicatie: Wat maakt in dat geval die startup tijd nou uit?
Sterker nog, als je voor een dergelijke taak een threadpool thread zou nemen, zou je andere functies waarbij ze wel nodig zijn ( bv van andere objecten van het framework zelf ) kunnen laten blocken omdat er geen threads meer beschikbaar zijn.

Je suggereert dat het direct gebruiken van een thread object het meest verschrikkelijke is wat je zou kunnen doen, maar de waarheid is simpelweg niet zo absoluut.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
farlane schreef op donderdag 24 oktober 2013 @ 23:59:
[...]

Een threadpool is er voor om kortdurende taken in een andere thread te kunnen laten draaien...
Provides a pool of threads that can be used to execute tasks, post work items, process asynchronous I/O, wait on behalf of other threads, and process timers.
Hoe kom jij op 'kortdurende'?? je kan prima langere taken draaien in een threadpool.
Sterker nog, een threadpool is niets meer dan een stukje management op je threads.
Het begrenst het maximale aantal tegelijk draaiende threads, het helpt de ontwikkelaar minder fouten maken, en (en nu komt het meest belangrijke, let op:) het HERGEBRUIKT threads, zodat je dus minder overhead hebt.
Er wordt echter helemaal niet verteld hoe lang de taak in die thread duurt, voor hetzelfde geld is dat een minuut of misschien wel gedurende de looptijd van de applicatie: Wat maakt in dat geval die startup tijd nou uit?
Sterker nog, als je voor een dergelijke taak een threadpool thread zou nemen, zou je andere functies waarbij ze wel nodig zijn ( bv van andere objecten van het framework zelf ) kunnen laten blocken omdat er geen threads meer beschikbaar zijn.
Ja en als je maar 1 core hebt dan 'blockt' (whatever je daarmee bedoelt) alles omdat er geen threads meer beschikbaar zijn??
Er bestaat niet zoiets als 'geen threads meer beschikbaar'
Je suggereert dat het direct gebruiken van een thread object het meest verschrikkelijke is wat je zou kunnen doen, maar de waarheid is simpelweg niet zo absoluut.
heb je mijn code voorbeeld gezien?

Ik claim niet dat het het meest verschrikkelijke is, maar ik zeg dat het zwaar inefficient is.
Ik reageer hierin op een reactie van R4gnax die zegt dat het gebruik van Thread erg gevaarlijk is en juist vaak fout gaat bij onervaren ontwikkelaars.

Dit is daar het perfecte voorbeeld van. Want ik gok dat de TS geen benul heeft van de overhead van zijn code.
Ik wil deze discussie niet maken over hoe jij mijn woorden interpreteert. Ik wil de melding meegeven dat je eigenlijk nooit 'new Thread()' moet gebruiken, omdat het zwaar inefficient is vooral wanneer je het vaker gaat doen.
Wanneer jou code door iemand anders in een loopje aangeroepen wordt zit je zo aan veel theads, en zeker wanneer je meer threads hebt dan cores gaat de inefficientie toenemen.
(dat is waarom je in een threadpool niet eens meer dan 64 threads tegelijk mag starten)

Je zit in dit topic een bad coding practice te verdedigen, en volgens mij help je daarmee onwetende ontwikkelaars niet verder...

edit:
leesvoer:
MSDN: [Threads] Create a new thread and reuse it

[ Voor 22% gewijzigd door BasieP op 25-10-2013 00:26 ]

This message was sent on 100% recyclable electrons.


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Dat code voorbeeld is een beetje oneerlijk. De code uit de TS is niet voor binnen een loopje, ik gok dat het binnen een STA thread wordt uitgevoerd, waarbij de .Join een nieuwe messageloop start (over de oude heen). Dat is lelijk, maar werkt wel degelijk.

Daarnaast zie ik in je voorbeeld dat 10.000 threads sequentieel starten+synchronisatie nog geen 2ms per thread lijkt te kosten. Die <2ms merk je echt niet bij userinteractie.

Neemt natuurlijk niet weg dat Tasks the way to go zijn in moderne code. :p
BasieP schreef op vrijdag 25 oktober 2013 @ 00:14:
je kan prima langere taken draaien in een threadpool.
De optie LongRunning maakt onder water eigenlijk effectief gewoon een nieuwe thread aan in de huidige implementatie. De semantiek is wellicht mooier, maar qua performance en uitvoering maakt het eigenlijk niet echt uit.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Verwijderd

Je noemt het gebruik van new Thread() een bad practice, maar een threadpool heeft ook nadelen. De threadpool imlementatie heeft geen weet van je thread precies aan het doen is. Als je een threadpool een actie laat uitvoeren welke grotendeels bestaat uit blocking waits, verspil je daarmee 1 thread uit je pool, die thread kan je vervolgens niet meer inzetten voor andere berekeningen. Iets wat met een losse thread wel kan.

Maar ondertussen doe je alsof het gebruik van new thread gelijk staat aan het gebruik van GOTO, dat is gewoonweg niet terecht.

[ Voor 3% gewijzigd door Verwijderd op 25-10-2013 00:33 ]


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 14:18
Verwijderd schreef op vrijdag 25 oktober 2013 @ 00:32:
[...] Maar ondertussen doe je alsof het gebruik van new thread gelijk staat aan het gebruik van GOTO, dat is gewoonweg niet terecht.
En ook GOTO heeft zijn momenten :P

Verwijderd

Ik gebruik GOTO regelmatig, maar bij sommigen overheerst nog steeds de gedachte dat er raptors op je afkomen als je het gebruikt... En het spawnen van een nieuwe thread hoort echt niet in die hoek thuis.

  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
Verwijderd schreef op vrijdag 25 oktober 2013 @ 00:42:
Ik gebruik GOTO regelmatig, maar bij sommigen overheerst nog steeds de gedachte dat er raptors op je afkomen als je het gebruikt... En het spawnen van een nieuwe thread hoort echt niet in die hoek thuis.
http://www.u.arizona.edu/...o_Considered_Harmful.html
*kuch*
Die beste man weet waarover hij het heeft ;)

This message was sent on 100% recyclable electrons.


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Zullen we weer ontopic? Thanks! d:)b

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
farlane schreef op donderdag 24 oktober 2013 @ 23:59:
Er wordt echter helemaal niet verteld hoe lang de taak in die thread duurt, voor hetzelfde geld is dat een minuut of misschien wel gedurende de looptijd van de applicatie: Wat maakt in dat geval die startup tijd nou uit?
Sterker nog, als je voor een dergelijke taak een threadpool thread zou nemen, zou je andere functies waarbij ze wel nodig zijn ( bv van andere objecten van het framework zelf ) kunnen laten blocken omdat er geen threads meer beschikbaar zijn.

Je suggereert dat het direct gebruiken van een thread object het meest verschrikkelijke is wat je zou kunnen doen, maar de waarheid is simpelweg niet zo absoluut.
Het probleem van de TS ligt in het managen van de control flow v/d thread (o.a. het afhandelen van exceptions) en daar hebben tasks wel degelijk toegevoegde waarde om de applicatie code simpel en maintainable te houden en vooral correct.

Performance kwam op dat punt eigenlijk nog helemaal niet ter sprake, maar zelfs als performance wel van belang zou zijn; het zou je wellicht verbazen hoe goed de Task Parallel Library daar mee omgaat.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13:12
BasieP schreef op vrijdag 25 oktober 2013 @ 00:14:
Hoe kom jij op 'kortdurende'?? je kan prima langere taken draaien in een threadpool.
Je hebt je nooit afgevraagd waar die threadpool vandaan komt en hoeveel threads er eigenlijk in zitten? Iemand die het zich wel afvroeg
Je zit in dit topic een bad coding practice te verdedigen, en volgens mij help je daarmee onwetende ontwikkelaars niet verder...
Je blijft een beetje hangen in je "new Thread() baaaaaad" verhaal, alsof je de enige echte goede manier in petto hebt. Als je niet verder wilt kijken dan je neus lang is prima, maar laat die beschuldigingen achterwege want ze zijn onterecht: Er zijn situaties waarin het aanmaken van een Thread een prima oplosssing is.
Het probleem van de TS ligt in het managen van de control flow v/d thread (o.a. het afhandelen van exceptions) en daar hebben tasks wel degelijk toegevoegde waarde om de applicatie code simpel en maintainable te houden en vooral correct.
Dat tasks toegevoegde waarde hebben is duidelijk, en ze kunnen wellicht helpen bij het probleem van de TS. Ik had alleen moeite met de opmerkingen van sommige posters (waaronder jijzelf) die suggereerden dat al het gebruik van Thread direct tot het einde der tijden zou leiden.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Caballeros
  • Registratie: November 2008
  • Niet online
Randmr schreef op woensdag 23 oktober 2013 @ 10:24:
Het is maar een voorbeeldje, ik gebruik deze constructie eigenlijk voor zowat al mijn processen die volledig autonoom (zonder user input) moeten lopen. (misschien ben ik gewoon al altijd 'verkeerd' bezig :P)

Ander voorbeeld: er moeten gegevens gedownload worden van een ftp, deze moeten verwerkt worden (aanpassing van formaat) en dan moet dit in een database inserted worden.

Dat downloaden van FTP kan een minuutje duren, soms meer, soms minder, als het bestand 10.000 lijnen heeft die ingelezen moeten worden om iets te veranderen duurt dat ook en daarna moeten er inserts gedaan worden in een database.

=> als ik dat gewoon in class Program { } gooi als statements onder elkaar dan hangt elke server met één core (toch??? zeker bij het inlezen van 10.000 lijntjes tekst en ik kan toch moeilijk een thread.sleep gebruiken bij elke iteratie).

=> veel exception handling is er niet nodig: ofwel lukt het ofwel niet (en dan wordt dit gelogd, volgende keer beter)
(volgens mij staat er tussen de oorlog die hier staat nog niet echt een antwoord)

Je kan toch ook gewoon om de 100 of 1000 regels een sleep doen of je thread prioriteit omlaag gooien.

Als het losse processen zijn, die autonoom iets moeten doen, heb je toch helemaal nergens threads voor nodig. Je programma is ook maar gewoon een thread, dus verschil in processorgebruik ga je er mee krijgen.

  • sig69
  • Registratie: Mei 2002
  • Laatst online: 13:43
Daar is het in het begin al fout gegaan, omdat de TS denk dat dat wel zo is en toen ging de discussie een hééél andere kant op. Maar goed, de TS is toch al afgehaakt volgens mij.

Roomba E5 te koop


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
farlane schreef op vrijdag 25 oktober 2013 @ 09:25:
Je hebt je nooit afgevraagd waar die threadpool vandaan komt en hoeveel threads er eigenlijk in zitten? Iemand die het zich wel afvroeg
Ik haal uit die link niet waarom je geen langere threads in een threadpool mag hebben draaien. Wel dat je het aantal niet te hoog moet hebben.
Je blijft een beetje hangen in je "new Thread() baaaaaad" verhaal, alsof je de enige echte goede manier in petto hebt. Als je niet verder wilt kijken dan je neus lang is prima, maar laat die beschuldigingen achterwege want ze zijn onterecht: Er zijn situaties waarin het aanmaken van een Thread een prima oplosssing is.
Ik zeg niet dat je nooit = new Thread mag gebruiken, en ik ben het met je eens dat het soms een prima oplossing is. Maar wat ik wel doe is doorbreien op ene opmerking van r4gnax waar ik het helemaal mee eens ben, namelijk dat je, zeker als beginnent ontwikkelaar eigenlijk te veel vrijheid hebt met de Thread class, en dat vooral nieuwe ontwikkelaars vaak fouten maken met die class.

Verder geef ik de enorme overhead aan, zeg dat (zeker in loops) je zo min mogelijk de =new Thread() moet gebruiken.
Verder heeft microsoft niet voor niets de Parallel class gemaakt, dus ik gok dat ze het redelijk met me eens zijn.

Verder heb je het over beschuldigingen... Welke precies? dat je de TS niet verder helpt als je hem lekker gaat vertellen dat hij = new Thread moet doen?
ik zei:
Je zit in dit topic een bad coding practice te verdedigen, en volgens mij help je daarmee onwetende ontwikkelaars niet verder...
Ik zei niet dat de wereld verging als je het wel doet, maar dan moet je er iets meer vanaf weten dat de TS doet.
Van mij mag jij ook assembly gaan schrijven, maar dat raad ik de meeste mensen gewoon AF.
Dan kun je een hele discussie starten over dat het soms echt nut heeft. Prima. Maar ik blijf het afraden.
Datzelfde geld voor dit verhaal. Ik blijf het afraden.
...alsof je de enige echte goede manier in petto hebt
Dat claim ik niet, dus doe dat alsjeblieft niet zo over laten komen.

Verder heb ik mezelf nu vaak genoeg herhaald.. dus er niet nog meer toetsenbord aan verslijten..

@TS: kijk eens naar die Parallel tasks, en hou in je achterhoofd dat Threading dmv de Thread class tricky is.

This message was sent on 100% recyclable electrons.


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Caelorum schreef op vrijdag 25 oktober 2013 @ 00:39:
[...]

En ook GOTO heeft zijn momenten :P
Goto in hogere talen (heb het ff niet over assembly oid) is over het algemeen een indicatie van een beginnende programmeur die zijn probleem niet kan vertalen in een goede programflow.

Stellen dat goto nodig is in sommige gevallen is stellen dat Java ed niet kunnen bestaan.

[ Voor 11% gewijzigd door Hydra op 25-10-2013 11:43 ]

https://niels.nu


  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Hydra schreef op vrijdag 25 oktober 2013 @ 11:42:
[...]
Stellen dat goto nodig is in sommige gevallen is stellen dat Java ed niet kunnen bestaan.
Ehm, niemand stelt hier dat Goto 'nodig' is? ;)
BasieP schreef op vrijdag 25 oktober 2013 @ 11:38:

@TS: kijk eens naar die Parallel tasks, en hou in je achterhoofd dat Threading dmv de Thread class tricky is.
Jeetje zeg, sinds wanneer is het niet gebruiken van 20 lagen abstractie ineens tricky. Er is niets mis met een Thread gebruiken. Je moet oppassen met wat je doet, en je doet het misschien een keer fout, maar daarmee leer je in ieder geval hoe het er in in de implementaties van Parrallel tasks en weet ik wat voor andere wrappers om Thread aan toe gaat.

Tuurlijk hebben thread pools, tasks en dergelijke echt hun nut wel, en het maakt je leven soms een stuk makkelijker, maar om nou gelijk een Thread af te doen als gevaarlijk en eng..

[ Voor 91% gewijzigd door EddoH op 25-10-2013 11:56 ]


  • pedorus
  • Registratie: Januari 2008
  • Niet online
BasieP schreef op vrijdag 25 oktober 2013 @ 11:38:
Ik haal uit die link niet waarom je geen langere threads in een threadpool mag hebben draaien. Wel dat je het aantal niet te hoog moet hebben.
Wachten in een thread pool taak is in ieder geval niet handig. Op dezelfde manier dat wachten als je aan de beurt bent bij de kassa niet handig is. Lange ononderbroken taken kunnen, net als bij de kassa, ook de wachtrij ophouden.
There are several scenarios in which it is appropriate to create and manage your own threads instead of using thread pool threads:
  • You require a foreground thread.
  • You require a thread to have a particular priority.
  • You have tasks that cause the thread to block for long periods of time. The thread pool has a maximum number of threads, so a large number of blocked thread pool threads might prevent tasks from starting.
  • You need to place threads into a single-threaded apartment. All ThreadPool threads are in the multithreaded apartment.
  • You need to have a stable identity associated with the thread, or to dedicate a thread to a task.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • BasieP
  • Registratie: Oktober 2000
  • Laatst online: 19-10 08:18
EddoH schreef op vrijdag 25 oktober 2013 @ 11:48:
Jeetje zeg, sinds wanneer is het niet gebruiken van 20 lagen abstractie ineens tricky.

Je moet oppassen met wat je doet, en je doet het misschien een keer fout,
Volgens mij is dat de definitie van tricky ;)
In ieder geval bedoel ik hetzelfde als jij...

Jij praat over 20 lagen abstractie alsof dat slecht is, maar abstractie is er niet voor niets, en als abstractie slecht zou zijn zouden we met z'n alle assembly programeren.

Wat ik zeker met je eens ben is dat op je bek gaan als ontwikkelaar goed is, want daar leer je van. :)

This message was sent on 100% recyclable electrons.


Verwijderd

BasieP schreef op vrijdag 25 oktober 2013 @ 11:38:
[...]

Ik haal uit die link niet waarom je geen langere threads in een threadpool mag hebben draaien. Wel dat je het aantal niet te hoog moet hebben.
Dat is hem nu juist. Wat is hoog? Misschien zit jouw klant op een singlecore systeem en start je 2 threads die met elkaar communicieren. Oeps! Deadlock. Misschien zit jij op een quadcore systeem en start je 2 threads die met elkaar communiceren. Ook dat kan leiden tot een dreadlock als je een third-party lib heeft die gebruik maakt van de threadpool. En wat denk je wat er gebeurt als je in een thread uit een threadpool gaat wachten op een andere thread in de threadpool?

Je kan in een applicatie simpelweg niet weten hoeveel threads er in je pool beschikbaar zijn tenzij je controle hebt over alle code.
Verder geef ik de enorme overhead aan, zeg dat (zeker in loops) je zo min mogelijk de =new Thread() moet gebruiken.
Als je threadpool in een loop van 10000 gebruikt, dan zou ik sowieso zeggen dat je verkeerd bezig bent. Het gebruik van X worker threads plus een queue lijkt mij dan een stuk praktischer omdat je dan niet constant context switched nodig hebt.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op vrijdag 25 oktober 2013 @ 12:48:
Misschien zit jouw klant op een singlecore systeem en start je 2 threads die met elkaar communicieren. Oeps! Deadlock.
:?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

Meestal maakt een threadpool implementatie 1 thread per fysieke core.

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Verwijderd schreef op vrijdag 25 oktober 2013 @ 13:54:
Meestal maakt een threadpool implementatie 1 thread per fysieke core.
Dan nog: :?

Als één thread moet wachten op werk v/d andere thread betekent dit namelijk dat die ene fysieke core vrijkomt voor de andere thread om wat werk te doen, totdat die andere thread weer gaat wachten op de eerdere thread. Het gaat pas mis als beide threads tegelijk op elkaar moeten gaan wachten en als dat kan gebeuren, dan gaat het ooit met meer fysieke cores ook gewoon fout...


@farlane:
Dit is een mooi voorbeeld van een heel simpel concept binnen parallel programming waar je meteen al iemand hebt die de boot mist, ondanks dat de persoon in kwestie toch echt niet dom is. Misschien dat je hiermee snapt waarom het blijven vasthouden aan kale threads niet slim is.

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

R4gnax schreef op vrijdag 25 oktober 2013 @ 20:43:
[...]

Dan nog: :?

Als één thread moet wachten op werk v/d andere thread betekent dit namelijk dat die ene fysieke core vrijkomt voor de andere thread om wat werk te doen, totdat die andere thread weer gaat wachten op de eerdere thread. Het gaat pas mis als beide threads tegelijk op elkaar moeten gaan wachten en als dat kan gebeuren, dan gaat het ooit met meer fysieke cores ook gewoon fout...
Darkstone bedoeld dat als alle threads uit de pool bezig/vergeven zijn, en 1 van je communicerende 'jobs'/'tasks' in de queue van de pool staat te wachten tot er een thread vrijkomt je een soort van deadlock situatie hebt: je thread die bezig is wacht op de job in de threadpool queue, die nooit een thread krijgt omdat die bezet zijn en mogelijk op de job in de queue wachten.

Verwijderd

R4gnax schreef op vrijdag 25 oktober 2013 @ 20:43:
[...]

Dan nog: :?

Als één thread moet wachten op werk v/d andere thread betekent dit namelijk dat die ene fysieke core vrijkomt voor de andere thread om wat werk te doen,
De hardware thread komt vrij, maar de thread uit de pool niet. Voorbeeld:

Een threadpool van 2 thread, de standaard allocatie bij 'een dualcore systeem'.
Jouw programma bestaande uit een producer-consumer pattern met 1 producer en 2 consumers.
Als beide consumers een thread uit de pool gealloceerd krijgen, heb je een dreadlock. De producer krijgt pas een thread als iemand anders zijn thread opgeeft. Dat gebeurt nooit, want de consumers wachten op een exit-token van de producer.

Met een globale threadpool heb je geen controle over het aantal threads was je krijgt, if any. Misschien slokt een ander deel van jouw programma alle threads in de pool op.

Ik zou een threadpool gebruiken als ik wat dingen moest doen die duur zijn om te berekenen. Een mutex aanroepen vanuit een threadpool leid sneller tot een deadlock dan vanuit een losse thread. Een synchrone I/O request of wait uitvoeren zorgt ervoor dat een thread uit de pool wordt verspild. Die thread kan je dan niet voor ander dingen gebruiken. (de hardware thread zelf natuurlijk wel). Als je zelf een threadje spawnt heb je daar geen last van, ten koste van wat overhead bij het aanmaken van de thread en een iets onhandigere interface.

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Verwijderd schreef op vrijdag 25 oktober 2013 @ 13:54:
Meestal maakt een threadpool implementatie 1 thread per fysieke core.
Verwijderd schreef op vrijdag 25 oktober 2013 @ 21:24:
[...]

De hardware thread komt vrij, maar de thread uit de pool niet. Voorbeeld:

Een threadpool van 2 thread, de standaard allocatie bij 'een dualcore systeem'.
Waar haal je het idee vandaan dat het standaard maximum voor het aantal threads in een pool zo zwaar gelimiteerd zou zijn?

De standaard voor het maximale aantal threads in een System.Threading.Threadpool was tot en met .NET 1.1 gezet op 25 maal het aantal beschikbare cores. In .NET 2.0 werd dit opgehoogd naar 50 maal en in 2.0 SP1 naar 250 maal.

Sinds .NET 4.0 is het aantal dynamisch en afhankelijk van meerdere factoren waaronder het aantal beschikbare cores, het beschikbaare geheugen, de frequentie waarmee threads gestart worden en hun gemiddelde levensduur.

[ Voor 28% gewijzigd door R4gnax op 26-10-2013 14:14 ]


Verwijderd

Bij de implementatie in Qt is dat zo.

Als het aantal threads in de pool veel hoger ligt dan het aantal cores.dan gaat het argument dat een threadpool efficiënter zou omgaan met zijn resources ook nergens op. Wie weet start jij 100x een zware berekening die een seconde duurt, en worden er veel meer threads aangemaakt dan daadwerkelijk zinvol zijn.

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Verwijderd schreef op vrijdag 25 oktober 2013 @ 21:24:
Een threadpool van 2 thread, de standaard allocatie bij 'een dualcore systeem'.
Hoe kom je daar nu bij? Threads hebben nogal eens te wachten op IO. Het zou nogal inefficient zijn om maar 1 thread per core te hebben.

https://niels.nu


Verwijderd

Hydra schreef op zaterdag 26 oktober 2013 @ 14:43:
[...]
Het zou nogal inefficient zijn om maar 1 thread per core te hebben.
Dat hangt geheel af van de use case. Ik kan zat situaties bedenken waar je juist niet meer threads dan cores wilt.

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Verwijderd schreef op zaterdag 26 oktober 2013 @ 14:19:
Bij de implementatie in Qt is dat zo.

Als het aantal threads in de pool veel hoger ligt dan het aantal cores.dan gaat het argument dat een threadpool efficiënter zou omgaan met zijn resources ook nergens op. Wie weet start jij 100x een zware berekening die een seconde duurt, en worden er veel meer threads aangemaakt dan daadwerkelijk zinvol zijn.
Behalve als dat ondervangt door de hoeveelheid threads die er per tijdseenheid aangemaakt mogen worden te limiteren. Dat is bijv. in .NET het geval. Threadpools maken in .NET snel de minimale hoeveelheid threads aan voor gebruik en bouwen dit daarna rustig aan in stapjes uit. Heb je veel korte taken, dan wordt een groot deel daarvan gewoon geparkeerd totdat er een nieuwe thread aangemaakt mag worden of bestaande thread vrijkomt. Netto gezien partitioneert de threadpool de load dus al over een semi-optimale hoeveelheid batches.
Pagina: 1