- SF800 Solar Speicher Tutorial         
Ergebnis 1 bis 10 von 94

Thema: pthread: was genau macht "joinable" und was macht "detached"?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    HaWe
    Gast
    ist es nicht so, dass seit den POSIX C Definitionen insb. zu pthread (irgendwann schon in den 90ern) das MT per pthread eingeführt wurde?
    Ich arbeite ja mit pthread, und seit C99 spätestens ist das ja Standard.
    Übrigens, ich habe jetzt erfolgreich eine Methode getestet, die ich von einem netten Forumsmember des Raspi Forums bekommen habe (Paeryn).
    Ist zwar auch nicht gerade leichte Kost, aber fügt sich prima in meine pthread MT Architektur ein!
    Und: Es klappt jetzt damit mit dem Abbrechen eines einzelnen Threads!

    Jetzt will ich sehen, ob ich ihn auch wieder starten kann und dann ob das auch auf die UART Kommunikation ausgeweitet werden kann...

    Code:
    // Quelle. https://www.raspberrypi.org/forums/posting.php?mode=quote&f=33&p=1481807
    #include <stdio.h>
    #include <pthread.h>
    #include <stdbool.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    volatile bool TASKS_ACTIVE = false;
    volatile bool HEARTBEAT = false;
    
    // This is the cleanup function for UART_thr, it will be called if the
    // thread is cancelled or exits via pthread_exit(). Use it to release any
    // resources the thread has.
    void UART_thr_cleanup(void* data)
    {
        printf("UART_thr cleanup.\n");
    }
    
    void* UART_thr(void* data)          // UART comm (now just stalling)
    {
        int old;
        if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old)) {
            printf("UART: Error setting async cancel state.\n");
            pthread_exit(NULL);
        }
        pthread_cleanup_push(UART_thr_cleanup, NULL);
        HEARTBEAT = true;
        for(int i = 0; i < 5; i++) {
            printf("UART: i = %d\n", i);
            sleep(1);
        }
        printf("UART: simulating stall\n");
        HEARTBEAT = false;
        while(1) ;  // mimics stalling forever
        pthread_cleanup_pop(true);
        return NULL;
    }
    
    
    // We pass in a pointer to the thread id which we may need to cancel
    void* WATCHER_thr(void* heartbeat_id)           // thread watcher
    {
        pthread_t heartbeat_thread_id = *(pthread_t*)heartbeat_id;
        bool THREAD_ACTIVE = true;
        printf("WATCHER: Checking heartbeat.\n");
        while(THREAD_ACTIVE)  {  //
            //  cancel UART thread if no heart beat detected
            if(!HEARTBEAT) {
                //  cancel UART thread  // <~~~~~~~~~ ????  pthread_kill ? pthread_cancel ?
                printf("WATCHER: Lost heartbeat, cancelling UART thread.\n");
                pthread_cancel(heartbeat_thread_id);
                THREAD_ACTIVE = false;
            }
        }
        TASKS_ACTIVE = false;
        return NULL;  //
    }
    
    
    //
    
    int main() {
    
        // threads
        pthread_t       thread0, thread1, thread2;
        pthread_attr_t  thread_attr;
        struct sched_param   param;
    
        // start multithreading
        pthread_attr_init(&thread_attr);  // Initialise the attributes
        pthread_attr_setschedpolicy(&thread_attr, SCHED_RR);  // Set attributes to RR policy
    
        param.sched_priority = 40;
        pthread_attr_setschedparam(&thread_attr, &param); // Set attributes to priority 40 (policy is already RR)
        pthread_create(&thread2, &thread_attr, UART_thr, NULL);    // medium  priority: UART
    
        param.sched_priority = 80;
        pthread_attr_setschedparam(&thread_attr, &param); // Set attributes to priority 80
        pthread_create(&thread0, &thread_attr, WATCHER_thr, &thread2);     // high priority: heartbeat monitor
    
        pthread_attr_destroy(&thread_attr); // We've done with the attributes
    
        TASKS_ACTIVE = true;
        while(TASKS_ACTIVE) {
            printf("MAIN: tasks active, waiting\n");
            sleep(1);
        }
        printf("MAIN: threads ended, goodbye.\n");
    
        // wait for threads to join before exiting
        pthread_join(thread0, NULL);
        //pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
    
        exit(0);
    }

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von HaWe Beitrag anzeigen
    ist es nicht so, dass seit den POSIX C Definitionen insb. zu pthread (irgendwann schon in den 90ern) das MT per pthread eingeführt wurde?
    Nein.
    Das wäre ja ein Schritt zurück zu Windows 3.11 mit darunter liegendem DOS ohne Speicherschutz. Ich zitiere mal hier (Prozess und Task sind Synonyme)

    What is a Thread?
    A thread is a single sequence stream within in a process. Because threads have some of the properties of processes, they are sometimes called lightweight processes.

    What are the differences between process and thread?
    Threads are not independent of one other like processes as a result threads shares with other threads their code section, data section and OS resources like open files and signals. But, like process, a thread has its own program counter (PC), a register set, and a stack space.
    Ein Thread kann also den anderen Threads den Code überschreiben, in den Speicher schreiben oder auch einen File schließen. Das macht einem im positiven Fall das Leben leichter (keine Interprozesskommunikation nötig) bringt aber im negativen Fall alle Threads gemeinsam zum Absturz.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  3. #3
    HaWe
    Gast
    wieso schreibst du jetzt was zu Windows? Windows ist a-priori nicht POSIX-kompatibel.
    Tatsächlich (habe nachgeguckt) is threads eine Standard POSIX Extension seit 1995:
    Threads is an API defined by the standard POSIX.1c, Threads extensions (IEEE Std 1003.1c-1995).
    https://en.wikipedia.org/wiki/POSIX_Threads

    Aber lassen wir das mit der Historie und den Grundsatzdiskussionen:
    pthread ist ANSI C99 Standard, pthread ist relativ einfach anzuwenden (sogar einfacher als std::thread finde ich), und es ist seit langem erprobt, bewährt und ohne Bugs.

    Ich bn ja selber kein ausgebildeter Programmierer sondern Laie und Hobby-Anwender, und als Laie kann ich sagen, dass man sich zwar schon einarbeiten und etliche Fragen klären muss, aber wenn man das tut, dann ist es auch für Laien anwendbar (das ist mit den ganzen Fuses und Interrupts in avrstudio sicher nicht anders).
    Immerhin ist pthread zur Implementierung deutlich weniger komplex als Subprozesse, daher würde ich pthread in jedem Falle den Vorzug geben.
    Geändert von HaWe (20.06.2019 um 08:34 Uhr) Grund: typo

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von HaWe Beitrag anzeigen
    wieso schreibst du jetzt was zu Windows?
    Weil das "Multitasking" von Windows 3.11 nur Threads kannte und keine Tasks. Unix benutzt schon immer Tasks und wird sicher nie sein "Multitasking" auf so eine unsichere Umgebung wie Threads umstellen, POSIX hin oder her.
    Aber lassen wir das mit der Historie und den Grundsatzdiskussionen:
    pthread ist ANSI C99 Standard, pthread ist relativ einfach anzuwenden (sogar einfacher als std::thread finde ich), und es ist seit langem erprobt, bewährt und ohne Bugs.
    Es geht nicht um Bugs im System, es geht um die, die Du programmierst. Führt ein Bug in einem deiner Threads zum Absturz oder überschreibt einer deiner Threads die Variablen eines anderen Threads, stürzt nicht nur der eine Thread sondern auch alle anderen ab. Dies ist der Nachteil, den man sich einhandelt, wenn man sich die Komplexität im Umgang mit Tasks sparen will. Und dies ist auch der Grund, warum Windows seit NT auch auf Tasks basiert (und damit erst wirklich brauchbar geworden ist).

    Immerhin ist pthread zur Implementierung deutlich weniger komplex als Subprozesse, daher würde ich pthread in jedem Falle den Vorzug geben.
    "There is no such thing as a free lunch"

    MfG Klebwax

    P.S.
    - dennoch müssen hnterher noch Speicher und Pointer etc. aufgeräumt werden, z.B. existiert immer noch ein thread-Handle über die thread-ID, und auch die wird erst durch pthread_join gelöscht.
    - auch wenn der Thread sich nicht selber beendet, sondern er über pthread_cancel beendet wurde, ist der Thread handle noch nicht geschlossen, auch das muss noch durch ein zusätzliches pthread_join erledigt werden.
    Das alles und noch viel, auf das du noch kommen wirst, erledigt bei einer Task das Betriebssystem.

    Zitat Zitat von Klebwax Beitrag anzeigen
    Zum Schluß stellt man dann fest, daß man ein eigenes Betriebssystem programmiert hat, das aber längst auf dem System vorhanden ist. Das eigene ist auch nicht einfacher als das vorhandene, dafür ist es nur von einem selbst getestet und es fehlen hunderte Seiten man-Pages. Wer schreibt schon sowas zum eigenen Code? Wegen der Threadüberwachung ist es sogar langsamer als ein System, das auf Tasks basiert.
    Geändert von Klebwax (20.06.2019 um 09:30 Uhr)
    Strom fließt auch durch krumme Drähte !

  5. #5
    HaWe
    Gast
    Deine Grundsatzdiskussionen helfen nicht wirklich weiter. In C aber ist immer schon vieles möglich, was zu Überschreiben von Speicherbereichen führt: In C muss nunmal der Programmierer aufpassen, was er tut, es ist von der Sprache her (fast) alles erlaubt, auch damit verbundene Fehler.
    Ich sehe auch nicht, dass du hier eine ernsthafte, praktikable Alternative zu pthread anbieten kannst, die u.a. auch halbwegs Hobbyprogrammierer-tauglich ist (Prozesse und Subprozesse mit pipes etc sind es definitv NICHT!).
    Also lassen wir jetzt bitte diese frustranen und sinnlosen Grundsatzdiskussionen

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von HaWe Beitrag anzeigen
    Deine Grundsatzdiskussionen helfen nicht wirklich weiter. In C aber ist immer schon vieles möglich, was zu Überschreiben von Speicherbereichen führt:
    Von einer Task in eine andere??

    In C muss nunmal der Programmierer aufpassen, was er tut, es ist von der Sprache her (fast) alles erlaubt, auch damit verbundene Fehler.
    Und das Multitasking sorgt dafür, daß es nicht jedesmal einen Reboot des Gesamtsystems gibt.

    Ich will auch nichts anbieten, ich will dich nur dazu bringen, die Konsequenzen deiner Entscheidung für Threads zu realisieren. "einfacher" wäre mir als Begründung zu wenig.

    Aber du hast recht, es ist genug gesagt, du hast nur noch nicht alles verstanden

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  7. #7
    HaWe
    Gast
    nein, ich denke du hast noch nicht alles verstanden, nämlich den Gesamtkontext und Sinn und Zweck der Anwendung, und POSIX pthread ist immerhin seit 20 Jahren eine etablierte ANSI C Standardlib.
    Irgendwas schlechtreden ohne konstruktive Alternativen ist aber in jedem Falle eine ziemlich billige Attitüde.

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.703
    Zitat Zitat von Klebwax Beitrag anzeigen
    .. Ich zitiere mal hier (Prozess und Task sind Synonyme) ..
    Danke für so ne Quellenangabe. Für mich sind "joinable", "detached", Thread, Prozess, Task etc im Kontext zu Programmen bzw. Programmierung eher Fremdwörter in denen ich nur sehr bescheidene Inhalte sehe, von irgendeinem Wissen zu Systemdesign mal ganz abgesehen. Das ist sehr persönlich - leider. Aber genau deswegen lese ich so etwas intensiv mit in der Hoffnung dass mal ein Schimmer aufleuchtet. Dein Link hilft da (ungemein?), danke. Und jetzt schweige ich hier wieder und lese nur noch.
    Ciao sagt der JoeamBerg

Ähnliche Themen

  1. Antworten: 10
    Letzter Beitrag: 01.11.2017, 12:53
  2. Antworten: 2
    Letzter Beitrag: 15.06.2011, 21:18
  3. "Optimization" macht debuggen schwer
    Von yaro im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 05.02.2010, 20:40
  4. "Soft-Reset?" und "Finger-Interrupt?"
    Von trapperjohn im Forum Asuro
    Antworten: 8
    Letzter Beitrag: 10.06.2008, 23:02
  5. ASM: was machen "swap" und "cbr" genau?
    Von RHS im Forum AVR Hardwarethemen
    Antworten: 3
    Letzter Beitrag: 18.08.2004, 17:16

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress