Προς το περιεχόμενο

Thread programming


Προτεινόμενες αναρτήσεις

Δημοσ.

...

π.χ έχεις μία υπηρεσία που διαβάζει το status μιας συσκευής, ενώ παράλληλα παρακολουθεί μία TCP port για κλήση που θα επιστρέψει το status της συσκευής για αυτή την κλήση, ενώ παράλληλα περιμένει την επόμενη κλήση για να γράψει ίσως κάτι στην συσκευή.

...

Δεν χρειαζεσαι νηματα ντε και καλα για αυτά, αλλά με νήματα σκέφτεσαι πιο λογικά σε αυτή την περίπτωση :)

 

@manic

Πολύ σωστά αυτά που εγραψες.Να προσθέσω οτι συνήθως διαλέγουμε να δημιουργήσουμε νέα νήματα αντί για διεργασίες,γιατί η εναλλαγη νημάτων είναι πιο γρήγορη.Επειδή κάθε φορά που γίνεται εναλλαγη(διεργασίας) πρέπει να γεμίσουμε το page table με το address space της νέας διεργασίας, χάνουμε αρκετούς κύκλους μηχανής προτου τρέξει η επόμενη εντολή.Άσε που χάνονται και οι μεταφράσεις στην TLB και η πρόσβαση στη μνήμη γίνεται αργή...

  • Like 1
Δημοσ.

Και ένα παράδειγμα σε C#

        void Fa()
        {
            for(int i = 0; i < 1000; i++)
                Console.Write("A");
        }

        void Fb()
        {
            for(int i = 0; i < 1000; i++)
                Console.Write("B");
        }

        void Test()  //ΑΑΑΑΑΑΑΑΑΑΑΑΑΑ...ΑΑΑΑΒΒΒΒΒ...ΒΒΒΒΒΒΒΒΒΒΒΒΒ
        {
            Fa();
            Fb();
        }

        void Test_Threads()    ////AAΒAΒΒΒAAΒΒAABBBA ..... AAABABAAAΒΒAAΒAABBBAA
        {
            new Thread(Fa).Start();
            new Thread(Fb).Start();
        }

 

 

H Test() τυπώνει 1000 φορές Α και μετά 1000 φορές Β.

Η Test_Threads() τυπώνει 1000 φορές Α και 1000 φορές Β σε "τυχαία" σειρά

Δημοσ.

Και ένα παράδειγμα σε C#

 

 

        void Fa()
        {
            for(int i = 0; i < 1000; i++)
                Console.Write("A");
        }

        void Fb()
        {
            for(int i = 0; i < 1000; i++)
                Console.Write("B");
        }

        void Test()  //ΑΑΑΑΑΑΑΑΑΑΑΑΑΑ...ΑΑΑΑΒΒΒΒΒ...ΒΒΒΒΒΒΒΒΒΒΒΒΒ
        {
            Fa();
            Fb();
        }

        void Test_Threads()    ////AAΒAΒΒΒAAΒΒAABBBA ..... AAABABAAAΒΒAAΒAABBBAA
        {
            new Thread(Fa).Start();
            new Thread(Fb).Start();
        }

 

 

 

H Test() τυπώνει 1000 φορές Α και μετά 1000 φορές Β.

Η Test_Threads() τυπώνει 1000 φορές Α και 1000 φορές Β σε "τυχαία" σειρά

 

Δάκρυσα... Τόσο εύκολα ξυπνάς threads στην C# εγώ έγινα "γκουρού" μέχρι να καταφέρω να κάνω αυτό π ήθελα στην C με POSIX....!

  • Like 2
Δημοσ.

Νομίζω ένα από τα αγαπημένα θέματα στον προγραμματισμό για μένα :)

Ειδικά σε Java ... μιας και κατάλαβες φίλε μου την φιλοσοφία προτείνω να εμβαθύνεις περισσότερο..

Δημοσ.

Δάκρυσα... Τόσο εύκολα ξυπνάς threads στην C# εγώ έγινα "γκουρού" μέχρι να καταφέρω να κάνω αυτό π ήθελα στην C με POSIX....!

 

Να τα αμολήσεις εύκολο είναι.

Το δυσκολο είναι να τα πειθαρχήσεις.

  • Like 1
Δημοσ.

Δάκρυσα... Τόσο εύκολα ξυπνάς threads στην C# εγώ έγινα "γκουρού" μέχρι να καταφέρω να κάνω αυτό π ήθελα στην C με POSIX....!

 

 

Εννοείται...!!

 

Άλλο C# και άλλο C. Managed Vs Unmanaged. 

 

Το θέμα είναι ότι σε μερικές εφαρμογές δεν έχεις τίποτα άλλο παρά C... οπότε πετάς τα ρούχα σου, φοράς τομάρια ζώων και ανακαλύπτεις ξανά τον τροχό, την φωτιά και άλλα χρήσιμα εργαλεία. Η πλάκα έρχεται σε μερικά πρότυπα της C που σου λένε/συνηστούν να αποφεύγεις μέχρι και την malloc!

Δημοσ.

Και ένα παράδειγμα σε C#

        void Fa()
        {
            for(int i = 0; i < 1000; i++)
                Console.Write("A");
        }

        void Fb()
        {
            for(int i = 0; i < 1000; i++)
                Console.Write("B");
        }

        void Test()  //ΑΑΑΑΑΑΑΑΑΑΑΑΑΑ...ΑΑΑΑΒΒΒΒΒ...ΒΒΒΒΒΒΒΒΒΒΒΒΒ
        {
            Fa();
            Fb();
        }

        void Test_Threads()    ////AAΒAΒΒΒAAΒΒAABBBA ..... AAABABAAAΒΒAAΒAABBBAA
        {
            new Thread(Fa).Start();
            new Thread(Fb).Start();
        }
 

 

H Test() τυπώνει 1000 φορές Α και μετά 1000 φορές Β.

Η Test_Threads() τυπώνει 1000 φορές Α και 1000 φορές Β σε "τυχαία" σειρά

 

 

OK το παράδειγμα, αλλά ξέρεις ότι με αυτό τον τρόπο έχεις 2 thread που θα τρέχουν και δεν θα σταματήσουν ποτέ, δημιουργώντας memory leak. :P

Δημοσ.

Όχι ρε συ, μόλις γίνει i=1000 τελιώνουν και δεν μένει κάτι

Ψευδαίσθηση.

 

Θα πρέπει να τα κάνεις join ή abort, διαφορετικά έχεις memory leak.

Δημοσ.
Thread  thr = new Thread(func)
thr.Start()

 

 

Το thr θα είναι έτοιμο προς μάζεμα (GC) όταν δε θα χρησιμοποιείται πλέον, όπως κάθε αντικείμενο.   
Δλδ αν δεν θα υπάρχουν άλλες αναφορές σ'αυτό, αμέσως μετά την Start().
Αυτό δεν έχει καμία σχέση με το πότε θα τελειώσει η func.
Για όσο δεν τελείωνει η func, το thread pool θα έχει 1 λιγότερο thread διαθέσιμο
Δημοσ.

Ο GC δεν καθαρίζει ό,τι τελειώνει άμεσα. 

 

Επίσης αναφέρωμαι σε services, η οποία θα τρέχει χωρίς επανεκκίνηση για μήνες και χρόνια σε κάποιο server. Και όχι σε κάποια desktop εφαρμογή που μπορεί να κλείσει κάποιος. 

 

Αν έχεις δεκάδες+ thread να ξεπηδάνε κάθε λεπτό, θα δεις ότι η μνήμη θα φτάσει τα εκατοντάδες MB, και να κολήσει εκεί για ώρες χωρίς να πέφτει, ακόμα και αν δεν γίνεται τίποτα. Π.χ για κάποιον που τραβά φωτογραφίες από 20+ κάμερες, και κάθε thread είναι ολόκληρη διεργασία που επιδρά σε φυσικές συσκευές (π.χ wago controller που διαχειρίζεται μπάρες κλπ, και έμμεσα την ροή φορτηγών στην είσοδο/έξοδο ενος λιμανιού), πρέπει να κάνεις αυτό το μικρό βήμα και μην αφήνεις τίποτα στην "τύχη" του. 

 

 

Και ένα hint, όσον αφορά το disposable. Ναι, δεν κάνει inherit από IDisposable άμεσα. 

Αλλά,  μπορείς να φτιάξεις μία κλάση "Managed Disposable" (η οποία είναι inherited από IDisposable) και από αυτή να κάνεις inherit την κλάση. ;)

Δημοσ.

Καθε thread θέλει 1MB επιπλέον, ανεξαρτητα την συναρτηση που εκτελούν. δλδ 20 threads  20MB επιπλέον.

 

H class Thread ειναι sealed και δεν σ αφηνει να κάνεις inherit
Αλλά αν σε άφηνε τι θα έγραφες στον κώδικα της Dispose() ?

 

class DisposableThread : Thread, IDisposable 
{
    public void Dispose()
    {
        
    }
}

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...