# Thread erstellen



## Winner (1. November 2007)

Hallo liebe gemeinde!

Ich bin dabei ein Programm zu erstellen, das Daten von einem Server empfängt. Das klappt soweit auch, ich kann diese auch in eine Datei bzw. Comport ausgeben. Aber jetzt das Problem, das ganze soll in Echtzeit laufen.

Und da ist meine Frage, kann mir einer erklären wie ich einen Thread schreibe. Damit müsste es gehen oder. Ich möchte das der Benutzer sowohl in eine Datei als auch in eine Datenbank oder auf den ComProt ausgeben kann. Aber da dieses auch zusammen passieren soll, muss ich doc einen oder mehrere Threads haben oder.

Wie definiere ich einen Thread und wie rufe ich ihn auf. Kann mir da wer weiterhelfen.

Gruß und besten danl


----------



## Faller (1. November 2007)

ich hab dazu mal nen paper erstellt vor kurzen das prog müsste selbst erklärrend sein

hier ma das paper über threads

*Thread Programmierung auf Windows und c mit Visuell studio 6.0 *

  Folgende Sachen sind in Thread Programmierung zu beachten 
  Der unterschied zwischen Prozess und Thread
  Kritische bereiche
  Und Mutexe
  Zu alle diesen dingen sollte man sich ein kleines bisschen bei Wikipedia belessen
http://de.wikipedia.org/wiki/Mutex
http://de.wikipedia.org/wiki/Thread
http://de.wikipedia.org/wiki/Kritischer_Bereich --> http://de.wikipedia.org/wiki/Kritischer_Abschnitt

  Ach und die Msdn nicht vergessen
http://msdn2.microsoft.com/de-de/library/172d2hhw(VS.80).aspx


  Nun zum eigentlichen Projekt:

  Als erstes erkläre ich die Einstellungen für das Projekt.

  Start ist ein normales Konsolen Programm.
  Nun Fügen man 1 .cpp (Quellcode Datei hinzu)
  Und 
  3 Header darein hinzu .h

  Dies ist eine Anleitung für das Deutsche Visuel Studio 6.0 Version.

  Nun klickt man auf 
  Projekt -> Einstellungen ->c/c++

  In „Kategorie“ geht man auf „Code Generation“ 
  Und dann auf Laufzeit Bibliothek -> Multithreaded 
















  Nun hier der Inhalt der Dateien 
  Die CPP Datei heist hier main.cpp:

  #include <windows.h>
  #include <stdio.h>
  #include <conio.h>
  #include <process.h>
  #include <time.h>
  #include "threads.h"
  int main() 
  {
              threads_verwaltung test;//klasse initialiesieren

              printf("Ich bin das Hauptprogramm\nIch schlise mich in 3 sek\n");
              test.Start_eines_threads();        

              //das haupt programm soll warten auf die threads
              Sleep(3000);
      //sind alle threads bendet dann die handel löschen
              printf("das haupt programm ist tot");

              return 0;
  }







  Die 1 und wichtigste Header Datei heißt 
  threads.h

  #include "Globale_fuer_threads.h"
  #include "Thread_1_zahlen.h"
  #include "Thread_2_buchstaben.h"




  //da das thema Mutex nicht gerade klein ist hier mal ein link um sich einen überblick zu schaffen
  ///      http://de.wikipedia.org/wiki/Mutex


  class threads_verwaltung
  {

  public:

              threads_verwaltung();  //konstruktor
              ~threads_verwaltung(); //dekonstruktor der kasse

              bool Start_eines_threads(); 

  private:
              unsigned int anzahl_threads;                 //die anzahl an gerade benutzten threads
              HANDLE  hConsoleOut;                //Handle für die console 


              CONSOLE_SCREEN_BUFFER_INFO csbiInfo;//Konsolen information
  };



  threads_verwaltung::threads_verwaltung()
  {
              //Threads könne sich nicht selbst löschen
              //da sie aber gelöscht werden müssen zähle ich mit vievile gestartet wurden um diese zu löschen
              anzahl_threads=0;



              //handel zu der konsole hollen
      hConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );

              //Informationen über die Konsole 
      GetConsoleScreenBufferInfo( hConsoleOut, &csbiInfo );


      //initialsierungen für die Mutex 
              //um den zugriff zu gefährleisten
      hScreenMutex = CreateMutex( NULL, FALSE, NULL );//für den Bildschrim (konsole
      hRunMutex = CreateMutex( NULL, TRUE, NULL );    //für die Cpu
  }



  //alle threads müssen gelöschen gelöscht werden
  threads_verwaltung::~threads_verwaltung()
  {


              //alle noch offenen Threads schliessen
              while (anzahl_threads > 0 )
      {

          ReleaseMutex(hRunMutex); //beim ersten durchlauf bring es nix da der Thread nicht darauf abgestimmt wurde mit dem runmutex zu arbeiten
                          //beim zweiten durchlauf wird der 1 thread bendet
          anzahl_threads--;   
      }


              //es darf erst das programm beendet werden wenn alle threads geschlossen sind
              //INFINITE ist ein standart konstante die dafür sogrt das eserst weider geht wenn alle thrads geschlossen sind
      WaitForSingleObject(hScreenMutex,INFINITE);

              //Handel schliessen

              CloseHandle( hScreenMutex );
      CloseHandle( hRunMutex );
      CloseHandle( hConsoleOut );

  }
  //Start der beiden threads
  //für jeden threads muss "anzahl_threads" erhöht werden
  bool threads_verwaltung::Start_eines_threads()
  {
              anzahl_threads++;
              _beginthread(thread_test,0,&anzahl_threads);

              anzahl_threads++;
              _beginthread(thread_test_a,0,&anzahl_threads);

              return true;
  }


Nun zu den andern Dateien

  Globale_fuer_threads.h

  extern int zugriff_von_beiden=0; //auf diese variable greifenn die beiden threads zu
  HANDLE  hScreenMutex;            //ob der sreenn zeichnen darf auf die konsole

  HANDLE  hRunMutex;               //ob die threads bendet wurden oder noch net

  //eine Mutex spricht ihrgentwie die eislenen threads an die frage ist wie
  //mutexe kann man nur in threads benutzen 
  //jedem Thread wird ein start eine mutex zugewiesen ohna aber ein neues feld oder arry zu benutzen
  //diese spieziellen Mutex ist nur abfragbar in dem thread
  //auserhalb kann man mit ReleaseMutex("name"); den Thread ansprechen der name muss sich nich 
  //ändern aber durch dieses imaginere mit geben muss man rückwärts einseln jeden thread verändern.


  Thread_1_zahlen.h

  //der thread an sich
  void thread_test( void *pMyID )
  {
              int i=0;
              printf("meine id ist %i\n",&pMyID);



              do
              {
                          //dies ist ein kritischer bereich deswegen muss er gespeert werden und wieder freigegeben werden
                          WaitForSingleObject( hScreenMutex, INFINITE );
                                     printf("text\n");
                          ReleaseMutex( hScreenMutex );

                          //WaitForSingleObject wartet kurz ob der Thread beendet wurde oder nicht erst wenn die zeit abgelauufen ist kommt der nächste durch gang 
              }while (WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT );



              printf("\nEnde des ersten Threads\n");



  }






  Thread_2_buchstaben.h

  //der thread an sich
  void thread_test_a( void *pMyID )
  {
              int i=0;
              printf("meine id ist %i\n",&pMyID);

              clock_t endOp, startOp;

              startOp = clock();
              WaitForSingleObject( hScreenMutex, INFINITE );
              printf("Der Thread arbeitet die buschstaben von 1 bis 100 ab\n");
              ReleaseMutex( hScreenMutex );

              for(i=0;i<100;i++)
              {
                          zugriff_von_beiden++;
                          WaitForSingleObject( hScreenMutex, INFINITE );
                          printf("ich gehöre zu %i ich habe garda zeichen %c\n",&pMyID,i+32);
                          if(zugriff_von_beiden==40)
                          {
                                     printf("\nes ist ein zugriff auf die variable von thread 2 %i\n\n",zugriff_von_beiden);
                          }
                          ReleaseMutex( hScreenMutex );
                          Sleep(1);
              }

              WaitForSingleObject( hScreenMutex, INFINITE );
              printf("Und Tschuess\n");

              endOp = clock();

              long difference = endOp - startOp;

              difference *= CLK_TCK;//Ticks pro Sekunde
              difference /= 100000;//Millisekunden zwischen zwei Zeitpunkten
              printf("die zeit die gebraucht für thread 1 %i,%i sekunden \n",difference/10,difference-(difference/10)*10);
              ReleaseMutex( hScreenMutex );



  }

hoffe es hilft als einsteige in threads.
ach du wirsd schon bemerken Threads zu debugenn ist hass an sich 

MFG Faller


----------



## Maggio (3. November 2007)

Ich versuchs mal etwas kürzer, ohne Visual Gedöns

Thread definieren:

DWORD WINAPI ThreadFunc(LPVOID);

Thread aufrufen:

HANDLE hThread;
DWORD  dwThreadID;
hThread = CreateThread(NULL,0,ThreadFunc,0,0,&dwThreadID);
CloseHandle(hThread);

Thread function:

DWORD WINAPI ThreadFunc(LPVOID data)
{
// was auch immer er da tun soll;
return 0;
}

Natürlich gibt es dabei eine Menge zu beachten, aber das hat Faller ja schon ausgiebig beschrieben


----------



## Teambeta (3. November 2007)

Hier nochmal im Code-Tag ( Was sehr tolles  )


```
#include <windows.h>
#include <stdio.h>

const int	iMaxTNum = 5;
int			toQuit = 0;		// Wird vom Thread überwacht und guckt, ob sein Wert enthalten ist um sich zu beenden.

struct targ
{
	int val;
};

DWORD WINAPI bla( void* param );

int main( void )
{
	targ		ThreadArgs[ iMaxTNum ];
	int			ThreadIDs[ iMaxTNum ];
	HANDLE		Threads[ iMaxTNum ];

	printf( "bla");
	CLRSCR

	for( int iCnt = 1; iCnt <= iMaxTNum; iCnt++ )
	{
		ThreadArgs[iCnt-1].val = iCnt;

		/* Sicherheitsstruktur ist nicht nötig, genauso wie die gesamte Größe des Threads für Speicher.
		** Danach geben wir eine Addresse zur Funktion an und die Argumente als void-zeiger.
		** Wir wollen den Thread einfach ganz normal, direkt starten, deswegen Param 5. 0.
		** In dem letztem Parameter empfangen wir die Thread ID */
		Threads[iCnt-1] = CreateThread( NULL, 0, bla, (void*)&ThreadArgs[iCnt-1], 0, (LPDWORD)&ThreadIDs[ iCnt-1 ] );

		/* Thread gestartet? */
		if( Threads[iCnt-1] == NULL )
		{
			printf( "Failed to start Thread %d\n", iCnt );
		}
		else
		{
			printf( "Thread %d started, got number %d\n", iCnt, ThreadIDs[ iCnt-1 ] );
		}
	}

	Sleep( 5000 );

	for( int iCnt = 0; iCnt < iMaxTNum; iCnt++ )
	{
		printf( "Thread %d is shutting down..\n", iCnt+1 );
		
		toQuit = iCnt+1;

		CloseHandle( Threads[iCnt] );
		
		Sleep( 1000 );
	}

	getchar();

	return 0;
}

DWORD WINAPI bla( void* param )
{
	targ *threadarg = (targ*)param;

	while( toQuit != threadarg->val )
	{
		printf( "Thread %d: Bla..\n", threadarg->val );

		Sleep( 500 );
	}
	
	return 0;
}
```


----------

