Wie realisiert man eine/n Hintergrundscheife / -prozess



  • Ja ist klar, dass Delete nur bei wxTHREAD_JOINABLE Threads funktioniert. Habe es bereits geändert. Nur bringt das nichts. Der Fehler tritt immernoch auf.



  • KRibel schrieb:

    Ja ist klar, dass Delete nur bei wxTHREAD_JOINABLE Threads funktioniert. Habe es bereits geändert. Nur bringt das nichts. Der Fehler tritt immernoch auf.

    Kann es sein, dass du auf die GUI auf deinem Thread aus zugreifst? Was macht die Funktion

    m_frame->writeValues( temp_values );
    

    ?
    Oder greifst du aus den veschiedenen Threads auf den gleichen Speicherbereich zu?

    Benutz mal einen Debugger und lokalisieren die Stelle, wo der Fehler auftritt.


  • Mod

    hm also:

    void MyFrame::butt_start_stopClick(wxCommandEvent& event)
    {
        if ( butt_start_stop->GetValue() )
        {
            MyWorkerThread *readTempRC = new MyWorkerThread( this ,CTD );
            readTempRC->Create();
            readTempRC->Run();
        }
        else
        {
            readTempRC->Delete();
        }
    }
    

    ^den Code finde ich schon mal sehr komisch.
    Der eine Thread widr lokal erstellt, der andere danach gelöscht.
    Und zwischen Thread und GUI solltest du per Event kommunizieren.



  • m_frame->writeValues( temp_values );
    

    temp_values ist ein Struckt aus drei Strings.
    Die Funktion writeValues ist eine Methode des Hauptframes und schreibt diese drei Strings in eintsprechende EditFelder.

    Das Problem ist, dass selbst wenn meine Entry-Funktion NUR aus einer while-Schleife besteht:

    while( TestDestroy() )
    {}
    

    , dass selbst dann der selbe Fehler auftritt.

    Nachtrag 19.06.07 - 22:43:
    Mir ist da bezüglich gleichzeitigem Zugriff was eingefallen. Das muss ich morgen überprüfen.



  • Zu Testzwecken habe ich mein WorkerThread folgender Maßen geändert:

    class WorkerThread : public wxThread
    {
        private:
            MyFrame *m_frame;
    
        public:
            WorkerThread( MyFrame *frame);
    
            virtual void *Entry();
            virtual void OnExit();
    };
    
    WorkerThread::WorkerThread( MyFrame *frame) : wxThread(wxTHREAD_JOINABLE)
    {
        m_frame = frame;
    }
    
    void *WorkerThread::Entry()
    {
        while( !TestDestroy() )
        {
    
            wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED , THREAD_WORKER_EVENT );
            event.SetString( _T( "Test" ) );
            wxPostEvent( m_frame , event );
            wxThread::Sleep(200);
        }
    
        return NULL;
    }
    
    void WorkerThread::OnExit()
    {
    }
    

    Die Methode die beim Event ausgeführt wird sieht so aus:

    void MyFrame::OnMyEvent(wxCommandEvent& event)
    {
        Textfeld->Clear();
        *Textfeld << event.GetString();
    }
    

    Der Text wird eingeblenden wie erwartet.

    Wenn ich debugge und ein Breakpoint vor Delete() setze ist alles in Ordnung. Kliche ich dann auf "Nächster Schritt" kommt die Fehlermeldung:

    Eine Zugriffsverletzung (Segmentation Fault) trat in Ihrem Programm auf.

    Was kann das sein?


  • Mod

    wie erstellst du den Thread zur Zeit?
    Kann es sein, das der Pointer der Delete aufruft, ungültig ist?



  • @phlox81:

    den Code finde ich schon mal sehr komisch.
    Der eine Thread widr lokal erstellt, der andere danach gelöscht.
    Und zwischen Thread und GUI solltest du per Event kommunizieren.

    Oh danke!!! Habe doch MyWorkerThread *readTempRC schon in meiner Headerdatei stehen.

    Habe den Code geändert:

    void MyFrame::butt_start_stopClick(wxCommandEvent& event)
    {
        if ( butt_start_stop->GetValue() )
        {
            readTempRC = new MyWorkerThread( this ,CTD );
            readTempRC->Create();
            readTempRC->Run();
        }
        else
        {
            readTempRC->Delete();
        }
    }
    

    und es funktioniert.

    Muss jetzt noch die passenden Methoden für die ganzen Events schreiben und dann passt es.

    Kann ich eigentlich durch ein Event an mein WorkerThread etwas senden?

    VIELN DANK NOCH EIN MAL!!!


  • Mod

    Wenn du deine Threadklasse auch von wxEvtHandler ableitest, kann sie auch Events empfangen.



  • @phlox81:
    was meinst du mit 'auch'?

    Etwa so?

    class WorkerThread : public wxThread : wxEvtHandler
    

  • Mod

    Ja, Mehrfachvererbung, allerdings ist deine Syntax falsch:

    class MyThread : public wxThread, public wxEvtHandler
    

    ist richtig.


Anmelden zum Antworten