- Labornetzteil AliExpress         
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
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von schorsch_76 Beitrag anzeigen
    Da du pthread_cancel ansprichts, hier gibt es etwas zu lesen für dich:
    https://lwn.net/Articles/683118/

    Das Problem das ich hier eben sehe, das mein Design mit den Prozessen nicht hat, sind nicht frei gegebene Betriebsystemresourcen wie bsp der offene Filedescriptor für ttyACM0.
    Das ist ein grundsätzliches Problem. Am Anfang glaubt man, man kann sich die Interprozesskommunikation sparen, wenn man Threads statt Tasks benutzt. Man kann einfach globale Variable verwenden. Dazu kommt noch die verbreitete Meinung, Taskwechsel verschenken Zeit gegenüber Threadwechseln. Irgendwann, wenn das System unübersichtlich geworden ist und sich z.B. die ersten Memoryleaks oder Deadlocks eingeschlichen haben, fängt man an, eine Thread- und Speicherüberwachung zu programmieren. 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.

    Daher sollte man am Anfang des Systemdesigns gut überlegen, ob es Sinn macht, ein eigenes Tasking-System (genauso wie eigene Kommunikationsprotokolle oder eine eigene Datenserialiesung) zu erfinden. Am Ende lauert immer das komplette Fiasko.

    MfG Klebwax
    Geändert von Klebwax (19.06.2019 um 10:08 Uhr)
    Strom fließt auch durch krumme Drähte !

  2. #2
    HaWe
    Gast
    Zitat Zitat von Klebwax Beitrag anzeigen
    Das ist ein grundsätzliches Problem. Am Anfang glaubt man, man kann sich die Interprozesskommunikation sparen, wenn man Threads statt Tasks benutzt. Man kann einfach globale Variable verwenden. Dazu kommt noch die verbreitete Meinung, Taskwechsel verschenken Zeit gegenüber Threadwechseln. Irgendwann, wenn das System unübersichtlich geworden ist und sich z.B. die ersten Memoryleaks oder Deadlocks eingeschlichen haben, fängt man an, eine Thread- und Speicherüberwachung zu programmieren. 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.

    Daher sollte man am Anfang des Systemdesigns gut überlegen, ob es Sinn macht, ein eigenes Tasking-System (genauso wie eigene Kommunikationsprotokolle oder eine eigene Datenserialiesung) zu erfinden. Am Ende lauert immer das komplette Fiasko.

    MfG Klebwax
    dein Einwand trifft hier nicht zu, denn wegen (höchstwahrscheinlich) kernel Zugriffen funktioniert hier keine UART Kommunikation über Stunden hinweg stabil in einer main loop (es hatte sich ja immer aufgehängt nach mehreren Minuten, wenn du dich recht erinnerst) , und wenn mal eine main loop hängen sollte, ist dann komplett Hopfen und Malz verloren.
    Außerdem ist aber ja doch das gesamte Prgrommdesign eh auf MT ausgelegt (SCHED_RR mit verschiedenen prios).
    Die Threadüberwachug aber läuft zwar in einem high prio Thread, aber später mit langen yields/delays von mindestens 100ms pro loop (oder noch viel länger), die auf einem quadcore überhaupt nicht ins Gewicht fallen, zumal die yield Zeiten in vollem Umfang vom Scheduler den anderen time slices zur Verfügung gestellt werden.

    - - - Aktualisiert - - -

    PS
    oder habe ich deinen Bezug falsch intepretiert?

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von HaWe Beitrag anzeigen
    dein Einwand trifft hier nicht zu, denn wegen (höchstwahrscheinlich) kernel Zugriffen funktioniert hier keine UART Kommunikation über Stunden hinweg stabil in einer main loop (es hatte sich ja immer aufgehängt nach mehreren Minuten, wenn du dich recht erinnerst) , und wenn mal eine main loop hängen sollte, ist dann komplett Hopfen und Malz verloren.
    Außerdem ist aber ja doch das gesamte Prgrommdesign eh auf MT ausgelegt (SCHED_RR mit verschiedenen prios).
    Die Threadüberwachug aber läuft zwar in einem high prio Thread, aber später mit langen yields/delays von mindestens 100ms pro loop (oder noch viel länger), die auf einem quadcore überhaupt nicht ins Gewicht fallen, zumal die yield Zeiten in vollem Umfang vom Scheduler den anderen time slices zur Verfügung gestellt werden.
    Du hast meinen Text nicht wirklich verstanden. Daher hier noch mal die wichtigsten Worte

    Threads statt Tasks
    MfG Klebwax

    Da du deinen Text ergänzt hast hier meine Ergänzung: Ja
    Strom fließt auch durch krumme Drähte !

  4. #4
    HaWe
    Gast
    meintest du mit Tasks die Prozesse und Sub-Prozesse mit dem pipe Ding von schorsch?

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    48
    Beiträge
    456
    @HaWe: Genau: Er meint man sollte die Aufgaben in einzelne Prozesse verlagern. Auch die Prozesse werden vom Scheduler des Betriebsystems richtig priorisiert.

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von schorsch_76 Beitrag anzeigen
    @HaWe: Genau: Er meint man sollte die Aufgaben in einzelne Prozesse verlagern.
    So einfach hab ich das nicht gesagt. Ich hab gesagt, daß man sich die Entscheidung ob Task oder Thread (oder auch beides) nicht zu leicht machen sollte. Ein Designfehler an dieser Stelle kann zum völligen Fehlschlag des Projektes führen.

    Auch die Prozesse werden vom Scheduler des Betriebsystems richtig priorisiert.
    "Auch" halte ich hier für eine unglückliche Formulierung. Unix, und das gilt auch für seine seine Clones, ist ein Multitasking System mit gekapselten Prozessen, die in eigenen Adressräumen laufen. Erst später sind Threads dazu gekommen. Der Scheduler kümmert sich also primär um Tasks und erst in zweiter Linie um die Threads der Tasks. Er arbeitet auch, wenn, wie früher. kein einziger Thread aufgesetzt wird.

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

  7. #7
    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);
    }

Ä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
  •  

LiFePO4 Speicher Test