Thread Array erzeugen



  • Hallo Leute, ich möchte ein Thread Array erstellen
    wie man hier in meinem Versuch sieht...

    DWORD GetNumCPUs()
    {
    	SYSTEM_INFO m_si = {0};
    	GetSystemInfo(&m_si);
    	return (DWORD)m_si.dwNumberOfProcessors;
    }
    
    void main()
    {
    	DWORD cpuam = GetNumCPUs();
    	const CPUAM = cpuam;
        HANDLE  hThread[cpuam]; 
    
    	for( int i=0; i<cpuam; i++ )
    	{
    		DWORD dwThreadParam[i] = i;
    		HANDLE hThread[i] = CreateThread (NULL,0,ThreadProc,&dwThreadParam[i],0,NULL);
    		SetThreadAffinityMask(hThread[i], i);
    	}
    ...
    ...
    ...
    }
    

    aber leider macht da der Compiler nicht mit, warum?

    Vielen Dank für eventuelle Hilfe.

    rom4o 😕



  • Hi,

    1. Waere nett wennste au gleich die Fehlermeldungen mit Posten koenntest
    2. Kann ich jetzt nur raten und ich denk es liegt an 2 Faktoren:
    - die weist einer const Variable einen Wert zu
    - du versuchst ein Array mit einer Variable als groessen Angabe zu definiern (geht nur mit C99 komformen Kompileren !?)

    Blessed Love C0de4Fun



  • Hier sind die konkreten Fehlermeldungen

    Zeile 12 - error C2057: Konstanter Ausdruck erwartet
    Zeile 12 - error C2466: Reservierung eines Feldes der konstanten Groesse 0 nicht moeglich
    Zeile 12 - error C2133: 'hThread' : Unbekannte Groesse
    Zeile 16 - error C2057: Konstanter Ausdruck erwartet
    Zeile 16 - error C2466: Reservierung eines Feldes der konstanten Groesse 0 nicht moeglich
    Zeile 16 - error C2440: 'initializing' : 'int' kann nicht in 'unsigned long []' konvertiert werden
    Zeile 17 - error C2057: Konstanter Ausdruck erwartet
    Zeile 17 - error C2466: Reservierung eines Feldes der konstanten Groesse 0 nicht moeglich
    Zeile 17 - error C2440: 'initializing' : 'int' kann nicht in 'unsigned long []' konvertiert werden

    Ich kann auch das ganze Programm posten wenns hilft....

    grüße rom4o



  • Wie schon gesagt wurde: du versuchst hier, bei deiner Array-Deklaration einen dynamischen, erst zur Laufzeit bekannten Wert für die Größe anzugeben. Das geht nicht (MS kennt kein C99). Da hilft auch der Umweg über eine const-Variable nicht (die übrigens bei dir gar keinen Typ hat! Du meinst wohl "const int"). Ein dynamisches Array musst du erzeugen, indem du mit malloc (C) oder new/new[] (C++) Speicher anforderst und ihn am Ende wieder mit free oder delete/delete[] freigibst (sonst gibt's ein Speicherleck!).



  • Ich hab sowas (mit BCB) gemacht, das klappt bestens!
    Die Threads sind eine eigene Klasse, die eine Fertigmeldung enthalten.
    Die Fertigmeldung wird am ende der Thraedfunktion gesetzt (Execute)

    //Funktion, die ein oder mehrere CPUs nutzt !!!
    FunktionFuerEineOderMehrereCPUs()
    {
      SYSTEM_INFO SystemInfo;
      DWORD PAM,SAM;
      int ActiveCPUs=0;
      int i;
      GetSystemInfo(&SystemInfo);
      if (GetProcessAffinityMask(GetCurrentProcess(),&PAM,&SAM)!=0)
      { for (i=0;i<32;i++)
        { if ((PAM & (1<<i))!=0)
          { ActiveCPUs++;
          }
        }
      }
      if (ActiveCPUs>1)
      {
    //    goto NoThreads;//Zu Testzwecken, falls andere Funkt nicht geht/ nicht fertig ist
        FunktionMitMehrerenThreads(ActiveCPUs);
      }
      else
      {
    NoThreads:
        //Hier "normale Abarbeitung!!!
    
       }
    }
    *********************************************************************************
    //Funktion für Multi- CPU- Nutzung
    FunktionMitMehrerenThreads(int ActiveCPUs)
    {
      TShiftThread **ShiftThreads; //Zeiger auf Array spezieller Threads "ShiftThread"
      Boolean AllThreadsFinished;
      DWORD ThreadRes;
    
      ...
    
            ShiftThreads=(TShiftThread**)malloc(sizeof(TShiftThread) * ThreadCount);
            if (ShiftThreads!=NULL)
            {
              memset(ShiftThreads,0,sizeof(TShiftThread) * ThreadCount);
              //Soviel Threads erzeugen/ starten, wie CPUs verfügbar
              for (i=0;i<ThreadCount;i++)
              {
                ShiftThreads[i]=new TShiftThread(passende Paramater hier!!!);
                ShiftThreads[i]->Resume();
              }
              //Auf Fertigmeldung aller Threads warten
              do
              {
                AllThreadsFinished=true;
                for (i=ThreadCount - 1;i>=0;i--)
                {
                  ThreadRes=WaitForSingleObject((void*)(ShiftThreads[i]->Handle),10);
                  if (!ShiftThreads[i]->Finished)
                  { AllThreadsFinished=false;
                  }
                }
              }
              while (!AllThreadsFinished);
              //Alle Threads deleten
              for (i=ThreadCount - 1;i>=0;i--)
              { ShiftThreads[i]->WaitFor(); //vorsichtshalber vorgesehen
                delete ShiftThreads[i];
                ShiftThreads[i]=NULL;
              }
              //fertig !!!
    
              free(ShiftThreads);
            }
    }
    


  • DWORD GetNumCPUs()
    {
    	SYSTEM_INFO m_si = {0};
    	GetSystemInfo(&m_si);
    	return (DWORD)m_si.dwNumberOfProcessors;
    }
    
    void main()
    {
    	DWORD cpuam = GetNumCPUs();
    	const CPUAM = cpuam;
        HANDLE  hThread[cpuam]; 
    
    	for( int i=0; i<cpuam; i++ )
    	{
    		DWORD dwThreadParam[i] = i;
                    // *********
                    // lösch das HANDLE vor hThread[i] weg
                    // *********
    		HANDLE hThread[i] = CreateThread (NULL,0,ThreadProc,&dwThreadParam[i],0,NULL);
    		SetThreadAffinityMask(hThread[i], i);
    	}
    ...
    ...
    ...
    }
    


  • Hallo Leute, vielen Dank für die hilfreichen Hinweise.
    Sorry aber konnte nicht früher antworten.

    Ich habe nun den Code wie zu sehen abgeändert:

    DWORD cpuam = GetNumCPUs();
        HANDLE  *hThread;
    	hThread = (HANDLE *) malloc(sizeof(HANDLE) * cpuam);
    
    	DWORD *dwThreadParam;
    	dwThreadParam = (DWORD *) malloc(sizeof(DWORD) * cpuam);
    
    	for( int i=0; i<cpuam; i++ )
    	{
    		dwThreadParam[i] = i;
    		hThread[i] = CreateThread (NULL,0,ThreadProc,&dwThreadParam[i],0,NULL);
    		SetThreadAffinityMask(hThread[i], i);
    	}
    

    Der Compiler zeigt keine Fehler an, jedoch stürzt das Programm sofort zur Laufzeit ab.
    Was ist denn da noch falsch.
    Ich habe das so ähnlich gelöst wie in dem Code von "DerAltenburger "
    jedoch konnte ich die Klasse TShiftThread nicht verwenden.
    Also irgendwas stimmt leider immernoch nicht.
    Freu mich über jede Hilfe.

    lg rom4o



  • Das hier funktioniert bei mir tadellos:

    DWORD GetNumCPUs() 
    { 
    	SYSTEM_INFO m_si = {0}; 
    	GetSystemInfo(&m_si); 
    	return (DWORD)m_si.dwNumberOfProcessors; 
    }
    
    DWORD __stdcall ThreadProc(PVOID pParam) {
    	for(int i=0;i<10;i++) {
    		std::cout << *((int*)pParam) << ": " << i << std::endl;
    	}
    	return 0;
    }
    
    int main() {
    	DWORD cpuam = GetNumCPUs(); 
    	HANDLE  *hThread; 
    	hThread = (HANDLE *) malloc(sizeof(HANDLE) * cpuam); 
    
    	DWORD *dwThreadParam; 
    	dwThreadParam = (DWORD *) malloc(sizeof(DWORD) * cpuam); 
    
    	for( int i=0; i<cpuam; i++ ) 
    	{ 
    		dwThreadParam[i] = i; 
    		hThread[i] = CreateThread (NULL,0,&ThreadProc,&dwThreadParam[i],0,NULL); 
    		SetThreadAffinityMask(hThread[i], i); 
    	}
    	getchar();
    }
    

    Da du nicht genauer beschrieben hast, wo das Programm abstürzt, schaust du am besten mal selbst, wo hier der genaue Unterschied ist. Der Debugger hilft meistens ganz gut.



  • rom4o schrieb:

    Hallo Leute, vielen Dank für die hilfreichen Hinweise.
    Sorry aber konnte nicht früher antworten.

    Ich habe nun den Code wie zu sehen abgeändert:

    DWORD cpuam = GetNumCPUs();
        HANDLE  *hThread;
    	hThread = (HANDLE *) malloc(sizeof(HANDLE) * cpuam);
    
    	DWORD *dwThreadParam;
    	dwThreadParam = (DWORD *) malloc(sizeof(DWORD) * cpuam);
    
    	for( int i=0; i<cpuam; i++ )
    	{
    		dwThreadParam[i] = i;
    		hThread[i] = CreateThread (NULL,0,ThreadProc,&dwThreadParam[i],0,NULL);
    		SetThreadAffinityMask(hThread[i], i);
    	}
    

    Der Compiler zeigt keine Fehler an, jedoch stürzt das Programm sofort zur Laufzeit ab.
    Was ist denn da noch falsch.
    Ich habe das so ähnlich gelöst wie in dem Code von "DerAltenburger "
    jedoch konnte ich die Klasse TShiftThread nicht verwenden.
    Also irgendwas stimmt leider immernoch nicht.
    Freu mich über jede Hilfe.

    lg rom4o

    Ist ja klar, TShiftThread ist eine vom Borland- Thread abgeleitete eigene Klasse. Die kennt nur mein Borländer.

    Doch das Prinzip sollte gehen.

    ABER:
    das Ergebnis von malloc (für die Threads) sollte doch in Zeiger auf Zeiger gespeichert werden???
    Zeiger auf ein Feld von Zeigern auf die Threads.

    Gruss
    Frank



  • Hallo Leute, ich habe das Problem gefunden.

    Ich habe vergessen

    for( i=0; i<cpuam; i++ )
    	{
    	    WaitForSingleObject( hThread[i], INFINITE );
    	}
    

    einzubinden, dann ging es auf ein Mal perfekt.

    Und ebenso habe ich die Handels dann geschlossen und gelöscht.

    for( i=0; i<cpuam; i++ )
    	{
    	    CloseHandle( hThread[i] );
    	}
    
    	for( i=0; i<cpuam; i++ )
    	{
    	    TerminateThread ( hThread[i], 0 );
    	}
    

    Wieder einmal habt Ihr mir sehr geholfen.
    Vielen Dank....

    Grüße rom4o



  • TerminateThread(..) sollte nicht benutzt werden.
    "Fahre" den Thread geordnet herunter, indem Du die Thread Funktion verlässt.
    Simon



  • Hallo, warum soll ich nicht TerminateThread(..) benutzen?
    Es funktioniert aber alles.
    Wie soll ich den Thread denn sonst schließen und die Ressourcen wieder freigeben?

    viele Grüße

    rom4o



  • Signalisiere dem Thread, dass er sich beenden soll...

    Bzgl. Warum nicht TerminateThread:
    http://blog.kalmbachnet.de/?postid=6
    http://blog.kalmbachnet.de/?postid=16
    http://blog.kalmbachnet.de/?postid=17


Log in to reply