pthread und Exception - unerwartetes Verhalten



  • Hallo hier erstmal der Code zu meinem Problem

    #include <cstdlib>
    #include <iostream>
    #include <pthread.h>
    #include <Exception>
    using namespace std;
    
    bool temp=true;
    
    void* ThreadMain(void *arg){
          try{     
    
              while(1){
                  if(!temp)
                      throw exception();
              }
          } catch(exception e){
          }
    
          cout << "lala" << endl;
    
          pthread_exit(NULL);
    }
    
    int main(int argc, char *argv[])
    {
    
        pthread_t threadID1;
        if (pthread_create(&threadID1, NULL, ThreadMain, NULL) != 0) {
                    cerr << "Unable to create thread" << endl;
                    exit(1);
        }
    
        pthread_t threadID2;
        if (pthread_create(&threadID2, NULL, ThreadMain, NULL) != 0) {
                    cerr << "Unable to create thread" << endl;
                    exit(1);
        }
    
        for(int i = 0; i<100; ++i)
                 cout << i << endl;
    
        temp = false;
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    Das ist natürlich nur ein extrem vereinfachtes Beispiel zu meinem Problem.
    Die schleife, die die Zahlen schreibt dient lediglich der verzoegerung.
    Das Problematische Verhalten ist nun, das die beiden Exceptions nicht korrekt geworfen bzw.gefangen werden, da lediglich ein einziges mal "lala" ausgegeben wird.
    Wenn man nach dem "temp = false" noch einen ausgabebefehl schreibt kommt folgendes :
    This application has requested the Runtime to terminate it
    in an unusual way...

    Ich habe schon eine Menge mit den Threads herumexperimentiert und habe nur unter der Verwendung von Exceptions dieses Verhalten.
    Ich nutze pthreads unter Dev-Cpp.

    Über einen Ratschlag oder Hinweis wär ich äußerst dankbar...



  • Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich hab mal deinen Code korrigiert und es hat bei mir auch das gewünschte Ergebnis. Wenn es bei dir nicht klappt liegt es an deiner Platform.

    Hier die korrigierten Fehler:

    • phtread.h ist ein C Header und deshalb ist ein extern "C" drum herum eingefügt worden.
    • Die Startfunktion für pthread_create() muss C Bindung haben, deshalb ein extern "C" davor.
    • Wir beenden die Threads korrekt indem wir mit phtread_join() auf diese warten.
    • Wenn man eine Verzögerung benötigt, dann richtig. Wir warten mit dem Unix sleep eine Sekunde lang.
    • temp ist eine Variable, die zwischen zwei Threads geteilt wird, deshalb muss der Zugriff darauf synchronisiert werden. Dafür nehmen wir einen Mutex. Ohne Mutex ist nicht sichergestellt, dass die Threads überhaupt eine Änderung von temp mitbekommen.
    • Der Zugriff auf std::cout muss vom Benutzer zwischen verschiedenen Threads synchronisiert werden. Zwei Threads dürfen nicht gleichzeitig auf std::cout rausschreiben. Dazu benutzen wir auch den Mutex.

    Anmerkung: Nach dem Werfen der Exception ist der Mutex noch gelockt. Deshalb können wir den für std::cout noch verwenden und geben diesen erst dann frei. Das was hier mit temp gemacht wurde, macht man bei Pthreads besser mit Condition Variablen. Mit diesen kann man Events an andere Threads schicken.

    #include <cstdlib> 
    #include <iostream> 
    
    extern "C" {
    #include <pthread.h> 
    #include <unistd.h>
    }
    
    using namespace std; 
    
    bool temp = true; 
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
    extern "C" void * ThreadMain(void *){ 
       try{     
          while(1){ 
             pthread_mutex_lock(&mutex);
          	 if(!temp)throw exception(); 
             pthread_mutex_unlock(&mutex);
          } 
       } catch(exception e){ 
       } 
    
       cout << "lala" << endl; 
       pthread_mutex_unlock(&mutex);
    
       return NULL;     
    } 
    
    int main() 
    { 
    
       pthread_t threadID1; 
       if (pthread_create(&threadID1, NULL, ThreadMain, NULL) != 0) { 
          cerr << "Unable to create thread" << endl; 
          exit(1); 
       } 
    
       pthread_t threadID2; 
       if (pthread_create(&threadID2, NULL, ThreadMain, NULL) != 0) { 
          cerr << "Unable to create thread" << endl; 
          exit(1); 
       } 
    
    //   for(int i = 0; i<100; ++i) 
    //           cout << i << endl; 
    
       sleep(1);       //Warte eine Sekunde
    
       pthread_mutex_lock(&mutex);
       temp = false; 
       pthread_mutex_unlock(&mutex);
    
       pthread_join(threadID1, NULL);
       pthread_join(threadID2, NULL);
    
       return EXIT_SUCCESS; 
    }
    


  • danke für den korrigierten code, werde ihn gleich mal übernehmen...

    ich denke ich werde mich noch einmal einträglich mit den pthreads befassen...
    allerdings muss ich nochmal darauf hinweisen, besonders in bezug auf mutex und gemeinsame schreib etc. nutzung, das diese bisher kein problem darstellte...
    das beispielprogramm läuft ohne exceptions perfekt ab und beide threads lesen die temp variable zum (fast) gleichen zeitpunkt korrekt und geben danach auch beide auf der console das gewünschte aus... mir sind die erwähnten verbesserungen durchaus einleuchtend, jedoch habe ich das gefühl das diese wenig mit dem problem der exceptions zu tun haben...

    habe es eben mal ausprobiert (allerdings ohne sleep, da dieser nicht erkannt wird) und es passiert im grunde genommen das gleiche. Was für einen Compiler verwendest du ?

    Dennoch nochmal danke



  • l4guna schrieb:

    danke für den korrigierten code, werde ihn gleich mal übernehmen...

    ich denke ich werde mich noch einmal einträglich mit den pthreads befassen...
    allerdings muss ich nochmal darauf hinweisen, besonders in bezug auf mutex und gemeinsame schreib etc. nutzung, das diese bisher kein problem darstellte...
    das beispielprogramm läuft ohne exceptions perfekt ab und beide threads lesen die temp variable zum (fast) gleichen zeitpunkt korrekt und geben danach auch beide auf der console das gewünschte aus... mir sind die erwähnten verbesserungen durchaus einleuchtend, jedoch habe ich das gefühl das diese wenig mit dem problem der exceptions zu tun haben...

    habe es eben mal ausprobiert (allerdings ohne sleep, da dieser nicht erkannt wird) und es passiert im grunde genommen das gleiche. Was für einen Compiler verwendest du ?

    Dennoch nochmal danke

    gcc 4.1 auf Opensuse 10.1.

    Bei Threads ist es sehr einfach Code zu schreiben, der die meiste Zeit läuft aber in ganz seltenen Fällen
    doch nicht das tut, was man möchte. Um die Korrektheit sicherzustellen, muss man dann doch Synchronisation betreiben.



  • nochmal danke für die hilfe
    habe das problem nun gefunden...
    habe eine alte version von pthreads verwendet, die für diesen fehler anscheinend verantwortlich war... das prog. läuft nun einwandfrei...


Anmelden zum Antworten