Frage zu Multithreading!



  • Kommt drauf an... Wenn die Aufgabenstellung war möglichst maximalen Schwachsinn mit Threads zu machen, dann ist das schon eine gute Lösung.

    Ansonsten würde es helfen zu wissen welche Aufgabe Du versuchst zu lösen, dann könnte man auch sagen wie man es richtig macht. Der Code den Du zuletzt gepostet hat ist jedenfalls alles andere als sinnvoll. So sollte man z.B. nie Thread.Abort() verwenden, weil das zu beliebigem Fehlverhalten des Codes führen kann der gerade in dem Thread ausgeführt wird.



  • Abort() und Join() habe ich soeben entfernt!
    Es wird ja schon bei ISALIVE kontrolliert ob dieser Thread fertig ist oder nicht.

    Zielsetzung war:

    Wie kann ich diesen Prozess in mehrere Threads aufteilen um einerseits meine Rechnerleistung voll auszuschöpfen
    und schneller mit dieser einen Aktion fertig zu werden!

    KomboErhöhen() zählt wie eine Art Schleife die Zahlen hoch!
    In dieser Schleife werden extrem viele Berechnungen ausgeführt und dauern auch extrem lang.
    Nur alleine den Main-Thread nacheinander berechnen zu lassen dauert zu lang!
    Die Idee war also: Sobald der Main-Thread die Schleife hochgezählt hat Gebe ich diese Aufgabe dem ersten Thread; Sobald der Main-Thread wieder die Schleife erhöht gebe ich diese dem 2.Thread wenn der 1.Thread noch nicht fertig ist!...
    Und speichere die Daten dann jeweils dem Thread entsprechend in eine eigene datei.



  • werkla4 schrieb:

    Zielsetzung war:

    Wie kann ich diesen Prozess in mehrere Threads aufteilen um einerseits meine Rechnerleistung voll auszuschöpfen
    und schneller mit dieser einen Aktion fertig zu werden!

    Das haengt stark von deinem Problem ab. Manche Probleme lassen sich garnicht so zerlegen. Daher solltest du wissen, ob sich die Aufgabe ueberhaupt sinnvoll parallelisieren laesst. Wenn du das nicht machst, dann bekommst du schnell andere Effekte.

    Merk dir am Besten zwei Gruende fuers Parallelisieren:
    1. Du hast Aufgaben ala GUI und richtige Anwendung, bei denen du dich z.B. nicht darauf konzentrieren moechtest, ob du gerade die Berechnung fortsetzen moechtest oder kurz die GUI neu zeichnen musst (zwei Threads und die Organisation wird leichter, jedoch muessen beide Teile synchronisiert werden).
    2. Du hast unabhaengige Programmteile, die sich nicht beeinflussen.

    Beim letzteren Teil kannst du wirklich Geschwindigkeit gewinnen.

    werkla4 schrieb:

    Nur alleine den Main-Thread nacheinander berechnen zu lassen dauert zu lang!

    Diese Aussage stimmt mit einem weit verbreiteten Mythos ueberein.

    Nur weil du mehr Kerne hast oder mehr Threads wird das Programm nicht schneller. Es gibt auch Szenarien, bei denen du bei sinnlosen Parallelisieren langsamere Programme bekommst. Du musst naemlich bedenken, dass die Threads auch verwaltet werden muessen und mit mehr Threads hat das Betriebssystem mehr zu tun und wenn dann noch die Threads schlecht synchronisiert werden, dann wird dein Programm ganz schnell mal langsamer.



  • werkla4 schrieb:

    Wie kann ich diesen Prozess in mehrere Threads aufteilen um einerseits meine Rechnerleistung voll auszuschöpfen
    und schneller mit dieser einen Aktion fertig zu werden!

    Ich habe Dich schonmal gebeten die anderen Methoden zu zeigen. Fertig, Berechnung, KomboErhöhen und wie sie heißen.

    werkla4 schrieb:

    Die Idee war also: Sobald der Main-Thread die Schleife hochgezählt hat Gebe ich diese Aufgabe dem ersten Thread; Sobald der Main-Thread wieder die Schleife erhöht gebe ich diese dem 2.Thread wenn der 1.Thread noch nicht fertig ist!...

    Producer-Consumer-Queue. Siehe Tutorial.

    Irgendwie willst Du nicht wirklich Hilfe, oder?



  • werkla4 schrieb:

    Es wird ja schon bei ISALIVE kontrolliert ob dieser Thread fertig ist oder nicht.

    Das ist falsch. IsAlive prüft ob der Thread läuft oder nicht. mit "Fertig"-Sein hat das nichts zu tuen.

    werkla4 schrieb:

    Wie kann ich diesen Prozess in mehrere Threads aufteilen [...]

    Wortklauberei, aber... Man teilet einen Prozess nicht in Threads auf. Threads laufen in einem Prozess...

    werkla4 schrieb:

    Die Idee war also: Sobald der Main-Thread die Schleife hochgezählt hat Gebe ich diese Aufgabe dem ersten Thread; Sobald der Main-Thread wieder die Schleife erhöht gebe ich diese dem 2.Thread wenn der 1.Thread noch nicht fertig ist!...

    Der Gedankengang zeigt deutlich das Du noch nicht begriffen hast wie Threads funktionieren. Wie man es machen würde: Partitionieren und verteilen. (Oder wie Caesar sagte: Teilen und herrschen)

    Also: Die Menge der Berechnungen in zwei Teilmengen zerlegen und jedem Thread eine dieser Teilmengen zur Abarbeitung geben die dieser dann selbstständig nacheinander berechnet.

    werkla4 schrieb:

    Und speichere die Daten dann jeweils dem Thread entsprechend in eine eigene datei.

    Und hier holt dich dann Amdahl's law ein ein Festplattenzugriffe sequentiell sind...



  • int[] Zahlenkombination = new int[2] { 0, 0 };
                bool Berechnen = true;
                int[] Kombo1, Kombo2;
                int AnzThreads = 2;
                int MaxZahl = 10;
    
                Thread t1 = new Thread(() => Fertig()); t1.Start();
                Thread t2 = new Thread(() => Fertig()); t2.Start();
    
                while (Berechnen)
                {
                    if (AnzThreads >= 1)
                        if (!t1.IsAlive)
                        {
                            if (Raus(Zahlenkombination, MaxZahl))
                                Berechnen = false;
    
                            KomboErhöhen(ref Zahlenkombination, MaxZahl);
                            if (Berechnen) //  Thread1
                            {
                                Kombo1 = new int[] { Zahlenkombination[0], Zahlenkombination[1] };
                                t1 = new Thread(() => Berechnung(Kombo1, 1));
                                t1.Start();
                            }
                        }
                    if (AnzThreads >= 2)
                        if (!t2.IsAlive)
                        {
                            if (Raus(Zahlenkombination, MaxZahl))
                                Berechnen = false;
    
                            KomboErhöhen(ref Zahlenkombination, MaxZahl);
                            if (Berechnen) //  Thread2
                            {
                                Kombo2 = new int[] { Zahlenkombination[0], Zahlenkombination[1] };
                                t2 = new Thread(() => Berechnung(Kombo2, 2));
                                t2.Start();
                            }
                        }
    
                    Thread.Sleep(100);
                }
                // Warte bis alle Threads fertig sind
                int AnzKontrolle = 0;
                bool ThreadsNichtFertig = true;
                do
                {
                    int AnzFertigeThreads = 0;
    
                    if (AnzThreads >= 1 && !t1.IsAlive)
                        AnzFertigeThreads++;
                    if (AnzThreads >= 2 && !t2.IsAlive)
                        AnzFertigeThreads++;
    
                    if (AnzFertigeThreads == AnzThreads)
                        ThreadsNichtFertig = false;
    
                    AnzKontrolle++;
    
                    Thread.Sleep(1000);
    
                } while (ThreadsNichtFertig);
                //Fertig mit Berechnungen
    
            void Berechnung(int[] Zahlenkombination, int Thread_Nr)
            {
                string Ordnerpfad = @"C:\Users\KW\Desktop\Arbeit\TEST";
                string CSV_ErgebnisPfad = Path.Combine(Ordnerpfad, "CSV_Thread" + Thread_Nr + ".csv");
    
                StreamWriter Schreiber = new StreamWriter(CSV_ErgebnisPfad, true);
                // Dies will ich natürlich nicht berechnen aber als kurzes Beispiel!! Das eine Berechnung in eine CSV Datei geschrieben wird.
                Schreiber.WriteLine("Zahlenkombination: " + Zahlenkombination[0] + "_" + Zahlenkombination[1] + " = " + (Zahlenkombination[0] + Zahlenkombination[1]).ToString());
                Schreiber.Close();
            }
    
            void Fertig()
            {
                return;
            }
    
            void KomboErhöhen(ref int[] Zahlenkombination, int Max)
            {
                bool Geändert = false;
    
                if (Zahlenkombination[1] >= Max - 1)
                {
                    Zahlenkombination[0]++;
                    Zahlenkombination[1] = Zahlenkombination[0] + 1;
                    Geändert = true;
                }
    
                if (!Geändert)
                {
                    Zahlenkombination[1]++;
                    if (Zahlenkombination[1] >= Max)
                    {
                        Zahlenkombination[0]++;
                        Zahlenkombination[1] = Zahlenkombination[0] + 1;
                    }
                }
    
            }
    
            bool Raus(int[] Zahlenkombination, int Max)
            {
                if (Zahlenkombination[0] >= Max - 1)
                    return true;
    
                return false;
            }
    


  • Oder kann mir den jemand zeigen wie ein kleines richtiges Beispiel aussieht?
    Vorraussetzung ist jeweils die Threads sollen aus einer Schleife heraus gebildet werden:

    int i=1;
    bool Berechnen = true;

    while(Berechnen)
    {
    // i%2 ==1 Starte ersten Thread, i++

    // i%2 ==0 Starte zweiten Thread, i++

    if(i>=10)
    Berechnen=false;
    }

    Leider habe ich nicht so viel Ahnung was da im Hintergrund eines Programm-Codes läuft aber leider benötige ich unbedingt diese Funktion (Multithreading zur besseren Auslastung meines Computers).
    Wie wir alle Wissen: "Unser wichtigstes Gut ist Zeit (und Gesundheit) !".



  • In meinem Test mit dem letzten gesamten Code verspüre ich nur eine Verschnellerung des Programms wenn Thread.Sleep() mit in der Berechnungsmethode eingebaut ist! Ansonsten ist es bis jetzt noch nicht spürbar 😞
    Außer der CPU geht hoch...



  • Alter Schwede. Das ist der WTF-Code der Woche. Das ist völlig absurd und falsch was Du da machst.

    Kannst Du mal eine Single-Thread-Lösung dessen posten, was Du eigentlich damit berechnen willst?
    Oder Eingabe-Ausgabe-Beispiele aufzeigen?

    Das ist in der Form nicht zu reparieren und muss neu geschrieben werden. Wenn ich genau weiß was zu tun ist, finde ich übers WE bestimmt mal etwas Zeit. Vorausgesetzt da lässt sich überhaupt etwas parallelisieren. Bisher schreibst Du ja nur in Dateien und von aufwändigen Berechnungen sehe ich nichts.


Anmelden zum Antworten