CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Feb 2005
    Location
    Madrid (Spain)
    Posts
    511

    [RESOLVED] Critical section

    Hi again.

    Now I'm trying to write a example of critical sections but it's not work. why?

    NOTE: main function only call Inicio function.

    Code:
    #define NTHREADS 500
    #define MAXCADENA 10
    #define MAXTIMESLEEP 50
    
    CRITICAL_SECTION CriticalSection_Cadena;
    
    void Inicio (void);
    char sCadena[MAXCADENA];
    int nNumero;
    
    int Aleatorio(int nMin, int nMax) {
    	UINT nNumero;	
    	rand_s(&nNumero);
    	int nRes = (UINT)((double)nNumero / (double) UINT_MAX * (double)nMax) + nMin;	
    	return nRes;
    }
    
    void WINAPI fx(void) {	
    	EnterCriticalSection(&CriticalSection_Cadena);
    
    		char c = Aleatorio(48, 90); // del 48 al 90 las letras
    		int nPos = Aleatorio(0, (MAXCADENA-1));	
    		sCadena[nPos] = c;	
    		nNumero = c;
    	
    	LeaveCriticalSection(&CriticalSection_Cadena);
    }
    
    void Inicio (void) {
    
    	srand(time(NULL));	
    	memset(sCadena, '-', sizeof(char) * MAXCADENA);
    
    	void (WINAPI *vfx[NTHREADS])(); // matriz de NTHREADS de punteros a funciones	
    	// Creamos las funciones
    	for(int i=0;i<NTHREADS;i++) {
    		vfx[i] = fx;
    	}
    
    	InitializeCriticalSection(&CriticalSection_Cadena);
    
    	HANDLE vhThread[NTHREADS];
    	// Abro los hilos
    	for(int i=0;i<NTHREADS;i++) {
    		vhThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)vfx[i], NULL, 0, 0);		
    	}
    
    	WaitForMultipleObjects(NTHREADS, vhThread,  TRUE, INFINITE);
    	sCadena[MAXCADENA-1] = '\0';	
    
    	for(int i=0;i<NTHREADS;i++) {
    		CloseHandle(vhThread[i]);
    	}
    
    	DeleteCriticalSection(&CriticalSection_Cadena); 
    
    	MessageBox(NULL, sCadena, "Cadena", MB_OK);	
    }
    Last edited by juanpast; May 1st, 2012 at 04:06 AM.

  2. #2
    Join Date
    Jan 2009
    Posts
    1,689

    Re: Critical section

    Show us the code for EnterCriticalSection / LeaveCriticalSection... Did you write them or did you get them from somewhere? I recommend using one of the more common thread libraries, pthread is the one I think most widely used, but Boost's is more C++ oriented. I do believe that std::thread will start becoming fairly standard in the next few years though. I'm quite sure it's very based on Boost.
    Last edited by ninja9578; April 30th, 2012 at 04:42 PM.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Critical section

    Quote Originally Posted by juanpast View Post
    Hi again.

    Now I'm trying to write a example of critical sections but it's not work. why?
    Please describe what you mean by "does not work".

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Critical section

    Quote Originally Posted by ninja9578 View Post
    What threading library is this? I recommend using one of the more common ones, pthread is the one I think most widely used, but Boost's is more C++ oriented.
    It's Windows. Probably should have posted in the Windows API forum.

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Feb 2005
    Location
    Madrid (Spain)
    Posts
    511

    Re: Critical section

    I created few threads. Now I create 500 threads and the program crass.

    I change the code and use the Critical Section. This is my code now:

    Code:
    #define NTHREADS 500
    #define MAXCADENA 10
    #define MAXTIMESLEEP 50
    
    CRITICAL_SECTION CriticalSection_Cadena;
    
    void Inicio (void);
    char sCadena[MAXCADENA];
    int nNumero;
    int nHilosEsperan;
    
    inline int Aleatorio(int nMin, int nMax) {
    	UINT nNumero;	
    	rand_s(&nNumero);
    	int nRes = (UINT) ((double)nNumero / (((double) UINT_MAX + nMin ) * (double)nMax) + nMin);
    	return nRes;
    }
    
    void WINAPI fx(void) {	
    	if(TryEnterCriticalSection(&CriticalSection_Cadena) != 0) {		
    		char c = Aleatorio(48, 90); // del 48 al 90 las letras
    		int nPos = Aleatorio(0, (MAXCADENA-1));	
    		sCadena[nPos] = c;	
    		nNumero = c;
    	} else {
    		Sleep(Aleatorio(0,10));
    		nHilosEsperan++;
    		fx();
    	}
    	LeaveCriticalSection(&CriticalSection_Cadena);
    }
    
    void Inicio (void) {	
    	
    	srand(time(NULL));	
    	memset(sCadena, '-', sizeof(char) * MAXCADENA);
    
    	void (WINAPI *vfx[NTHREADS])(); // matriz de NTHREADS de punteros a funciones	
    	// Creamos las funciones
    	for(int i=0;i<NTHREADS;i++) {
    		vfx[i] = fx;
    	}
    
    	nHilosEsperan = 0;
    
    	InitializeCriticalSection(&CriticalSection_Cadena);
    
    	HANDLE vhThread[NTHREADS];
    	// Abro los hilos
    	for(int i=0;i<NTHREADS;i++) {
    		vhThread[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)vfx[i], NULL, 0, 0);		
    	}
    
    	WaitForMultipleObjects(NTHREADS, vhThread,  TRUE, INFINITE);
    	sCadena[MAXCADENA-1] = '\0';	
    
    	for(int i=0;i<NTHREADS;i++) {
    		CloseHandle(vhThread[i]);
    	}
    
    	DeleteCriticalSection(&CriticalSection_Cadena); 
    
    	MessageBox(NULL, sCadena, "Cadena", MB_OK);	
    }
    Is fine the code remarks in bold type?
    Last edited by juanpast; April 30th, 2012 at 06:10 PM. Reason: Change code

  6. #6
    Join Date
    May 2009
    Posts
    2,413

    Re: Critical section

    Quote Originally Posted by juanpast View Post
    Now I create 500 threads and the program crass.
    Do you get a stack overflow?

    I would suspect the recursive call to fx within fx. Try and replace it with an equivalent loop.
    Last edited by nuzzle; May 1st, 2012 at 12:33 AM.

  7. #7
    Join Date
    Feb 2005
    Location
    Madrid (Spain)
    Posts
    511

    Re: Critical section

    No, access violation as i want.

    As you suggest I change the code, now is that:

    Code:
    void WINAPI fxCriticalSection(void) {	
    	while (TryEnterCriticalSection(&CriticalSection_Cadena) == 0) {		
    		Sleep(Aleatorio(0,10));
    		nHilosEsperan++;
    	}
    
    	char c = Aleatorio(97, 122); // del 97 al 122 las letras
    	int nPos = Aleatorio(0, (MAXCADENA-1));	
    	sCadena[nPos] = c;	
    	nNumero = c;
    	
    	LeaveCriticalSection(&CriticalSection_Cadena);
    }
    It works fine.

    Thank you for your suggest.

    Best regards, Toño.

  8. #8
    Join Date
    May 2009
    Posts
    2,413

    Re: Critical section

    Quote Originally Posted by juanpast View Post
    It works fine.
    Glad it worked. The bug was probably a stack overflow that manifested itself as an access violation.

    The more threads you started the more threads were likely to be refused access to the critical section and the bigger the chance some thread made too many recursive calls causing the stack to overflow.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured