Synchronisation von Threads will nicht klappen



  • Abend Leute

    Ich arbeite zurzeit mit Threads, aber wenn man Threads nicht synchronisiert gibt es ja bekanntlich nur schmarrn. das heißt, es kommen ganz strange werte bei variablen raus, oder es gibt nen absturz. Deshalb muss man sie ja synchronisieren. Aber das klappt bei mir ja überhaupt nicht.

    Version 1:

    SECURITY_ATTRIBUTES sa;
        ZeroMemory(&sa,sizeof(sa));
        sa.nLength = sizeof(sa);
        sa.bInheritHandle = TRUE;
    
        HANDLE Mutex = CreateMutex(&sa,TRUE,NULL);
    
        if(WaitForSingleObject(Mutex,5000) != WAIT_OBJECT_0)
            MessageBeep(-1);
    
        cout << params.Audio->VERSION<< endl;
    
        ReleaseMutex(Mutex);
    
        MessageBox(NULL,"Hallo","!!!",MB_OK | MB_ICONERROR);
    
        CloseHandle(Mutex);
    

    Version2:

    CRITICAL_SECTION cs;
        InitializeCriticalSection(&cs);
    
        EnterCriticalSection(&cs);
        cout << params.Audio->VERSION << endl;
        LeaveCriticalSection(&cs);
    

    Bei beiden Versionen kommt das gleiche wie bei

    cout << params.Audio->VERSION << endl;
    

    raus. Nämlich nur Müll.

    Ich mach schon ewig rum, bitte rettet mich und hilft mir. Wäre super nett von euch.
    MFG Nitromaus



  • Was du da synchronisieren willst ist ja nur die Ausgabe und nicht der schreibende Zugriff auf die Variablen. Was kommt denn raus? Gib mal den Output.



  • Hi,

    man darf soweit ich weiß CRITICAL_SECTION cs nicht im Thread erstellen und InitiateCriticalSection muss auch vor erstellung der Threads ausgeführt werden, ich glaub cs muss global sein bzw. jeder Thread muss dieselbe Variable verwenden, und nicht die eigene Instanz von cs.



  • Man könnte auch mit Events arbeiten.
    CreateEvent(), SetEvent(), WaitForSingleObject() etc...



  • Mann muss nicht nur für Schreibzugriffe sperren, sondern auch für Lesezugriffe.
    Ok das mit den Critical Section probiere ich mal dass die global sind.
    Wäre nett wenn einer aber die geanue Ursache weißt.

    PS: Es kommt jedes mal ein anderer Output, und ab und zu stürzt das Prgramm halt ab

    PPS: Kann mir einer ein gutes Tutorial geben über die Sychronisierung von Threads mit der WinApi (nicht MFC)



  • Wo muss denn jetzt genau eine Critical Section initialisiert werden? In irgendeinem Thread muss es ja passieren? 😕



  • Jetzt auch noch das Problem wenn ich eine Critical Section global mache:

    Main.obj : error LNK2005: "struct _RTL_CRITICAL_SECTION g_cs" (?g_cs@@3U_RTL_CRITICAL_SECTION@@A) already defined in CAudio.obj
    Main.obj : error LNK2005: "struct _RTL_CRITICAL_SECTION g_cs" (?g_cs@@3U_RTL_CRITICAL_SECTION@@A) already defined in CAudio.obj
    Main.obj : warning LNK4006: "struct _RTL_CRITICAL_SECTION g_cs" (?g_cs@@3U_RTL_CRITICAL_SECTION@@A) already defined in CAudio.obj; second definition ignored

    was heißt denn jetzt das wieder.



  • Hast du in deinen Headern Include Guards benutzt? Irgendwas wird halt doppelt definiert



  • Oh ich habs ausversehen über den IncludeGuard geschrieben, jetzt hab ich es drunter, aber jetzt kommt noch:

    Main.obj : error LNK2005: "struct _RTL_CRITICAL_SECTION g_cs" (?g_cs@@3U_RTL_CRITICAL_SECTION@@A) already defined in CAudio.obj
    Main.obj : warning LNK4006: "struct _RTL_CRITICAL_SECTION g_cs" (?g_cs@@3U_RTL_CRITICAL_SECTION@@A) already defined in CAudio.obj; second definition ignored
    Creating library Debug/CAudio.lib and object Debug/CAudio.exp



  • lad mal den quelltext mit projektdateien hoch und wir finden den fehler in ein paar sekunden



  • ne ne das geht nicht, das ist ein größeres projekt 😃
    Aber was ist denn das beste. CriticalSections Events, Mutexe, Semaphoren



  • jaja, immer diese anti-open-source-programmierer 😞 😡

    beste für deine Situtation natürlich Critical Sections!



  • ne ich find meinen code nur so peinlich 😃



  • trau dich...keiner wird lachen und keiner wird dir irgendeine idee klauen. wir wollen dir nur helfen die beiden fehler zu berichtigen! 🙄



  • So, das mit den mehrfach definierten symbolen hab ich gelöst, ein kleiner leichtsinnsfehler.

    Könnte mir bitte einer ein kleines beispiel schreiben. Wäre super



  • @Nitromaus

    Mann muss nicht nur für Schreibzugriffe sperren, sondern auch für Lesezugriffe.

    Warum?
    Wenn 8 Threads von einer Variable lesen, dann bekommen doch alle das gleiche, also warum sperren?
    Sperren muss man, sobald ein Thread Schreibzugriff hat!



  • Komisch, beim Lesen einer Variable, die auf einen gültigen Zeiger zeigt kommt nur Schmarrn raus. Wenn ich aber die Variable im Hauptthread auslese kommt das richtige raus. kann das noch einen anderen grund haben.

    Und noch was. Ist es richtig so zu synchronisieren.

    CRITICAL_SECTION sc

    InitalializeCriticalSection(&cs);

    Im neuen Thread:
    EnterCriticalSection(&cs);
    //Variablenzugriff
    LeaveCriticalSection(&cs);

    am ende des programms:
    DeleteCriticalSection(&cs);

    Is das so richtig



  • Sagt mir nur ob das richtig ist, dann hör ich auf zu nerven



  • ...bitte...



  • ja, richtig 😉

    P.S. Beispiel, wenn man mal 10 Sekunden in die MSDN schauen würde:

    // Global variable
    CRITICAL_SECTION CriticalSection; 
    
    void main()
    {
        ...
    
        // Initialize the critical section one time only.
        InitializeCriticalSection(&CriticalSection); 
    
        ...
    
        // Release resources used by the critical section object.
        DeleteCriticalSection(&CriticalSection)
    }
    
    DWORD WINAPI ThreadProc( LPVOID lpParameter )
    {
        ...
    
        // Request ownership of the critical section.
        __try 
        {
            EnterCriticalSection(&CriticalSection); 
    
            // Access the shared resource.
        }
        __finally 
        {
            // Release ownership of the critical section.
            LeaveCriticalSection(&CriticalSection);
        }
    
        ...
    
    }
    

    [ Dieser Beitrag wurde am 29.10.2002 um 08:57 Uhr von RenéG editiert. ]


Anmelden zum Antworten