Welchen Include für Critical Section



  • Hallo, ich bin Anfänger was c++ angeht.

    Ich wollte mal Multithreadding ausprobieren und habe mir folgenden code zusammengewurschtelt:

    #include <windows.h>
    #include <stdio.h>
    
    #define MAX_THREADS 3 
    
    class Point 
    { 
    
    private: 
    
       int m_x; 
       int m_y; 
    
    public: 
       void setX(int x) 
       { 
    
          m_x = x; 
    
       } 
    
       void setY(int y) 
       { 
    
          m_y = y; 
    
       } 
    
       void gibaus() {
    
    	printf("%d "  ,(int)m_x  );	
    	printf("%d \n",(int)m_y  );
    
       }
    
    };
    Point p;
    
    DWORD WINAPI ThreadFunc(LPVOID data)
    {
    
    	for (int index=0; index<50; index++) {
    
    	p.setX((int) data);
    	p.setY((int) data);
    	p.gibaus();
    
    	} 
    
    	return((DWORD)data);
    
    } 
    
    void main(void)
    {
    
    	HANDLE hThread[MAX_THREADS];		
    	DWORD  dwThreadID[MAX_THREADS];		
    
    	printf("\nAlle Threads starten...\n");
    
    	for (int index=0; index<MAX_THREADS; index++) {
    
    		hThread[index] = CreateThread(NULL,						
    												0,							
    			   									ThreadFunc,				
    												(LPVOID)index,			
    												0,							
    												&dwThreadID[index]);	
    	} 
    
    	for (index=0; index<25; index++) {
    
    	p.setX(4);
    	p.setY(4);
    	p.gibaus();
    
    	} 
    
    	WaitForMultipleObjects(	MAX_THREADS,
    									hThread,			
    									TRUE,			
    									INFINITE);		
    
    	Sleep(4000);
    
    	for (index=0; index<MAX_THREADS; index++)
    		CloseHandle(hThread[index]);
    
    	printf("\nAlle Threads beendet.\n");
    
    }
    

    Jetzt wollte ich versuchen den Zugriff auf "Point" mit Critical Sections Sicher zu machen.

    Leider weiß ich nicht wie. Genauer, was ich includiern muß, welche Lib ich einbinden muß und wie genau die benötigten Befehle ich nehmen muß.

    Ich habe auch schon Google benutzt, finde aber immer nur so komische Beispiele in denen Klassen für die Threads benutzt werden, die ich gar nicht habe.

    PS. Ich benutze den Visual C++ 6.0



  • #include <windows.h>
    

    Und die Funktionen heissen
    - InitializeCriticalSection
    - EnterCriticalSection
    - LeaveCriticalSection
    - DeleteCriticalSection



  • Danke, aber es ist doch nicht soo einfach, wie ich dachte.
    Könnte BITTE Jemand dies in mein kleines Testprogramm einbauen?



  • Also , was mich irgendwie irrietiert ist, dass man ein Pointer auf ein "Critical Section Object" angeben soll. Aber ich müßte ja gar nicht das ganze Objekt "Point" absichern sondern nur die Beiden Zeilen in

    void setXY(int x,int y) 
       { 
               //Hier sichern beginnen
                m_x = x;
                m_y = y;
               //und hier beenden
    
       }
    

    Wenn ich jetzt diese Funktion verwende



  • MisterX schrieb:

    Könnte BITTE Jemand dies in mein kleines Testprogramm einbauen?

    in der main, bevor die threads gestartet werden: InitializeCriticalSection
    in der threadproc. vor die schleife: EnterCriticalSection
    ...und hinter der schleife: LeaveCriticalSection



  • OK, ich habe es versucht, doch ich komme mit dem
    "LPCRITICAL_SECTION lpCriticalSection" nicht zurecht.
    (Sogar mal was in der MSDN gefunden 🙂 )

    Kann mir das nicht doch Jemand mal einbauen, sonnst muß ich wieder 1000 Fragen zu diesem neuen Problem stellen, denn an den Beispiel lernt man doch am schnellsten.



  • Das heisst doch nicht anderes, als dass du eine Adresse übergeben sollst. 🙄

    CRITICAL_SECTION CriSect;
    
    main (..)
    {
        ....
        InitializeCriticalSection (&CriSect);
        ....
    }
    

    Usw.

    [Edit]Rechtschreibung[/Edit]



  • MisterX schrieb:

    OK, ich habe es versucht, doch ich komme mit dem
    "LPCRITICAL_SECTION lpCriticalSection" nicht zurecht.
    (Sogar mal was in der MSDN gefunden 🙂 )

    Dann lies doch einfach ein paar Zeilen weiter - "LPCRITICAL_SECTION" ist ein Pointer auf eine CRITICAL_SECTION, d.h. du mußt dort die Adresse (Stichwort &) eines CRITICAL_SECTION-Objekt übergeben, das du vorher definiert hast.



  • JUHU, es klappt jetzt, DANKE.

    Aber ich habe auch

    Parameters
    lpCriticalSection 
    [out] Pointer to the critical section object.
    

    gelesen.

    Aber wie kommt man darauf, dass das Objekt

    CRITICAL_SECTION

    mit Bindestrich heißen soll, wenn in der MSDN

    [out] Pointer to the "critical section" object.
    

    steht? 😕

    Mir ist schon klar, das es keine Leerzeichen enthalten darf, aber ich habe Vieles Probiert: Kleingeschrieben mit Bindestrich, groß mit Unterstrich, nur leider die richtige Version nicht.



  • MisterX schrieb:

    Aber wie kommt man darauf, dass das Objekt

    CRITICAL_SECTION

    mit Bindestrich heißen soll, wenn in der MSDN

    [out] Pointer to the "critical section" object.
    

    steht? 😕

    Indem man einfach ein wenig weiter liest:

    MSDN Library schrieb:

    The process is responsible for allocating the memory used by a critical section object, which it can do by declaring a variable of type CRITICAL_SECTION



  • DANKE!!!!!!!,

    jetzt habe ich erst mal verstanden, wie so ein MSDN Artikel generell aufgebaut ist 😃 😃

    Noch eine Frage zum Thema:
    Kann ich die Critical Section auch in mein Objekt selbst einbauen etwa so:

    class Point 
    { 
    
    private: 
    
    	CRITICAL_SECTION CriSect;
        int m_x; 
        int m_y; 
    
    public: 
    
    	Point () {
    
    	InitializeCriticalSection(&CriSect); 
    	}
    
       void setXY(int x,int y) 
       { 
          EnterCriticalSection(&CriSect);
    			m_x = x; 
    			m_y = y;
          LeaveCriticalSection(&CriSect) ;
    
       } 
    
       void gibaus() {
    	    EnterCriticalSection(&CriSect);
    			printf("%d "  ,(int)m_x  );	
    			printf("%d \n",(int)m_y  );
    		LeaveCriticalSection(&CriSect) ;
       }
    
    };
    

    oder ist das falsch?



  • Fast richtig - jetzt brauchst du nur einen Destruktor, der DeleteCriticalSection() aufruft (und entsprechend der "Rule of Three" einen Copy-Ctor und Zuweisungsoperator, sonst steht dir ein Systemcrash bevor).



  • Sowas würde man aber in der Realität nie programmieren. Man verschiebt die Thread-Synchronisation weiter nach aussen.



  • jetzt habe ich den Konstruktor eingebaut

    class Point 
    { 
    
    private: 
    
        CRITICAL_SECTION CriSect; 
        int m_x; 
        int m_y; 
    
    public: 
    
        Point () { 
          InitializeCriticalSection(&CriSect); 
        } 
    
    	~Point () {
    		DeleteCriticalSection(&CriSect);
    	}
    
       void setXY(int x,int y) 
       { 
          EnterCriticalSection(&CriSect); 
                m_x = x; 
                m_y = y; 
          LeaveCriticalSection(&CriSect) ; 
    
       } 
    
       void gibaus() { 
            EnterCriticalSection(&CriSect); 
                printf("%d "  ,(int)m_x  );    
                printf("%d \n",(int)m_y  ); 
            LeaveCriticalSection(&CriSect) ; 
       } 
    
    };
    

    Aber was ist mit "Rule of Three" gemeint?
    Wenn ich danach suche erhalte ich immer Theroien zu 3 großen marktbeherschenden Firmen 😕

    Und was ist ein einen Copy Construktor?



  • CStoll schrieb:

    sonst steht dir ein Systemcrash bevor

    ach quatsch. windows verträgt eine ganze menge 😉



  • MisterX schrieb:

    Aber was ist mit "Rule of Three" gemeint?
    Wenn ich danach suche erhalte ich immer Theroien zu 3 großen marktbeherschenden Firmen 😕

    Kurzform: Wenn eine Klasse eine der "großen 3" Methoden (Destruktor, Copy-Construktor, operator=) benötigt, benötigt sie typischerweise alle drei.

    oder ausführlicher für deinen Fall:
    Dein Dtor zerlegt die Critical Section - die vom Compiler erzeugten Kopier-Methoden kopieren diese jedoch blind weiter. D.h. wenn ein Point-Objekt kopiert wird, arbeiten beide Objekte mit der selben Critical Section (das führt im besten Fall dazu, daß sie sich gegenseitig aussperren, im schlimmsten Fall versuchst du irgendwann, eine nicht-initialisierte CritSec zu verwenden.

    @net: Wenn Windows das kompensieren kann, hast du viel Glück gehabt - ich würde mich nicht darauf verlassen 😉


Anmelden zum Antworten