Multithreading... der schnelle Weg zur Verzweiflung



  • Hey,

    ich hab' vor kurzem ein kleines Programm geschrieben, um automatisiert MD5 Prüfsummen zu verwalten. Jetzt hab' ich mir naiverweise überlegt, ich bau mal "schnell" Multithreading Unterstützung ein, um die Performance (auf meinem Core2Duo) zu verdoppeln... Das hab' ich vor einiger Zeit schon mal erfolgreich hingekriegt, wenn es mich auch extremst Nerven gekostet hat, das ganze zu debuggen und stabil zu kriegen.

    Jedenfalls dachte ich, diesmal würde es klappen.... Nach zwei Tagen des erfolglosen Debuggens... nach zwei Tagen, an denen ich meinen kompletten Feierabend für diesen *** geopfert hab, frag ich doch mal Leute, die davon vielleicht etwas mehr Ahnung haben 🙂

    Das Problem ist simpel: Ich habe das unten stehende Programm. Der main Thread erzeugt 30 Threads, die im Prinzip nichts machen. Egal. Jedenfalls stützt es mir ständig ab. Und damit meine ich nicht die Exception die ich werfe, sondern betriebssystemseitig:

    http://img410.imageshack.us/img410/8933/bild1un0.th.jpg

    #include <iostream>
    #include "windows.h"
    
    using namespace std;
    
    CRITICAL_SECTION critSectOutputAccess;
    
    //inline
    DWORD WINAPI calculateMD5HashSingle(void* lparam)
    {
        EnterCriticalSection(&critSectOutputAccess);
        string gster = "3423423434";
        string gst2er = "3423423434";
        string gszt2er = "3423423434";
        string gste2r = "3423423434";
        string gster2 = "3423423434";
        string gste3r = "3423423434";
        string gst3er = "3423423434";
        string g3ster = "3423423434";
        string gs3ter = "3423423434";
        LeaveCriticalSection(&critSectOutputAccess);
        return 0;
    }
    
    int main()
    {
        try
        {
            int test = 30;
            HANDLE* threadHandles = new HANDLE[test];
            DWORD*  threadIDs     = new DWORD[test];
    
            InitializeCriticalSection(&critSectOutputAccess);
    
            for (int i = 0; i < test; ++i)
            {
                threadHandles[i] = CreateThread(0,0,calculateMD5HashSingle,0,0,&threadIDs[i]);
                //WaitForSingleObject(threadHandles[i],INFINITE);
            }
            if (WaitForMultipleObjects(test, threadHandles, TRUE, INFINITE) == WAIT_FAILED)
                cout<<"wait failed "<<"error code "<<GetLastError()<<endl;
    
            DeleteCriticalSection(&critSectOutputAccess);
    
            throw 123;
        }
        catch (int& theException)
        {
            cout<<theException<<endl;
        }
        return 0;
    }
    

    Weiß jemand, warum dieses kleine Programm nicht stabil läuft?

    Nur zur Info. Ich verwende Codeblocks, aktuelle Nightly mit MinGW und gcc-g++-3.4.5, eben die "current" Distribution.

    Viele Grüße,
    ZenJu



  • Vielleicht noch ne kleine Anmerkung, zu meiner Definition von "stabil laufen"... Das erwartete Verhalten für micht wäre, dass die Exception korrekt abgefangen wird 😃

    Ich weiß das Programm macht so nicht viel Sinn, aber es enthält die Essenz des Fehlers mit dem ich mich rumärgere.

    Der Fehler tritt nicht auf, wenn ich
    - keine Exception werfe oder
    - keine Strings in der Threadfunktion verwende oder
    - immer nur einen Thread gleichzeitig laufen lasse

    Es scheint mir fast ein recht komplexer Fehler zu sein.... oder das sind alles nur Symptome und die Ursache liegt woanders...

    wie auch immer... Multithreaded Programmierung muss ich langsam mal in den Griff kriegen 🙂



  • ZenJu schrieb:

    Vielleicht noch ne kleine Anmerkung, zu meiner Definition von "stabil laufen"... Das erwartete Verhalten für micht wäre, dass die Exception korrekt abgefangen wird 😃

    welche exception?

    //edit ahh sehs...



  • Versuch mal _beginthreadex statt CreateThread.
    Und guck mal ob der MinGW ne Option vonwegen Threadsafe Runtime ja/nein hat.



  • Und guck mal ob der MinGW ne Option vonwegen Threadsafe Runtime ja/nein hat.

    Heureka! Es funktioniert! Nach einigem Googlen habe ich herausgefunden, dass MinGW die Option -mthreads für den Linker anbietet.

    Das Programm läuft jetzt einwandfrei!

    Ich frage mich nur, warum diese Option so schlecht dokumentiert ist. Selbst auf der MinGW Seite hab ich darüber nichts gefunden. Dafür, dass sie für Multithreading unabdingbar scheint! 👎

    Erst hier bin ich darauf aufmerksam geworden http://kometbomb.net/2007/05/14/mthreads-mthreads-mthreads/

    ... nach dem freundlichem Hinweis über mir 🙂



  • Ich frage mich nur, warum diese Option so schlecht dokumentiert ist.

    Jo, das frage ich mich bei den verschiedensten Dingen auch oft.


Anmelden zum Antworten