Threadanwendung



  • Hi,
    Ich will mal grob sagen ich habe 2 Programme die ich zusammenfügen will; bzw mein Programm soll 2 Befehle gleichzeitig ausführen. Nach lesen in Foren und so bin ich auf sogenannte "Threads" gestossen.
    Einmal soll er von der Seriellen Schnittstelle lauschen und auf meinen PC, wo ich lausche soll man das Programm mit ESC beenden.
    Mein funktionsfähiges Programm sieht im moment so aus:

    #include <conio.h>
    #include "Tserial.h"
    #include <stdio.h>
    #include <windows.h>	
    #define ESC 27
    char taste;
    int c, d;
    int main(){
    
    	Tserial*com;
    	FILE*datei;
    
    	// Initialisierung (Seriellen Port und eine Datei öffnen)
    	com=new Tserial();
    	com->connect("COM1", 9600 , spNONE);
    
    	datei=fopen("c:\\asdf.txt","a");
    
    // Programmschleife (Seriellen Port abfragen und bei Tastendruck Programm beenden)
    	while(taste != ESC){	
    		if (com->getNbrOfBytes()>0)	{
    			c = (int) com->getChar();
    			printf("%c",c);   
    			fprintf(datei,"%c",c);
    			if(c==ESC) break;
    		} else {
    			// System entlasten Programm macht 250 Millisekunden nichts
    			Sleep(250);
    		}
    
    		//if (feof(stdin)) printf("EOF on STDIN\n"); //wirkungslos!
    
    	}
    
    // Aufräumen (Datei schließen, Seriellen Port schließen und Objekt wieder freigeben)
    
    	fclose(datei);
        com->disconnect();
        delete com;
        com = 0;
    
    return 0;
    }
    

    hinzuzufügen wäre etwas wie

    if(scanf("%lf",&d)==EOF)break;
    

    welches aber durch die Threads nicht geblockt wird.

    Ich habe mir shcon diverse tutorials durchgelesen
    http://www.codeworx.org/cpp_tuts_1_5.php
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__beginthread.2c_._beginthreadex.asp
    aber ich verstehe noch nicht ganz wie ich diese jetzt verbinden soll.

    Ich bitte um vernünftige Antworten und nicht wie lern erstmal was anderes, da ich diese Aufgabe lösen muss und auch will. Boost-Threads kann ich hier nicht installieren, da das Programm vieeeelll zu gross ist.

    Benutzen tue ich Visual Basic C++ Kompiler.



  • Nach ANSI-Standart ist das glaub ich nicht möglich... Schau dir mal die process.h an!



  • Muss ich dann eine Win32 API Anwendung machen?



  • Ne, ist nicht nötig!



  • Threads sind im Prinzip ganz einfach: du wirfst einen an (mit _beginthread z.B.) und sagst ihm (über eine Funktionsadresse), was er tun soll. Diese Funktion wird dann einfach im Hintergrund ausgeführt - fertig. Trickreich dabei ist nur die Synchronisation und Kommunikation zwischen den Threads. Dazu solltest du dich noch recht eingehend informieren - Stichworte Events, Critical Sections, Mutexes, ...



  • Ich hab mir jetzt mal einen Beispiel heruntergeladen und da hab ich ein paar Fragen:

    #define WIN32_LEAN_AND_MEAN  // Kein MFC Zeugs *arg*
    #include <windows.h>
    #include <windowsx.h>
    #include <stdio.h>
    #define MAX_THREADS 3 //Definiton
    
    // --------------------------------------------------------------------------------------------
    
    // ============================================================================================
    // Funktionen
    // ============================================================================================
    
    DWORD WINAPI ThreadFunc(LPVOID data)
    {
    	// Gibt 50 ein Zeichen mit einer Verzögerung aus
    
    	for (int index=0; index<50; index++) {
    		printf("%d ",(int)data+1);		// Wert ausgeben
    		Sleep(100);						// Verzöger ein bisschen das ganze
    	} // end for index
    
    	// gibt den Wert zurück den du bekommen hast
    	return((DWORD)data);
    
    } // end ThreadFunc
    
    // --------------------------------------------------------------------------------------------
    
    void main(void)
    {
    
    	HANDLE hThread[MAX_THREADS];			// Handles auf die Threads
    	DWORD  dwThreadID[MAX_THREADS];			// IDs der Threads
    
    	printf("\nAlle Threads starten...\n");
    
    	// Alle Threads starten
    	for (int index=0; index<MAX_THREADS; index++) {
    
    		hThread[index] = CreateThread(NULL,							// Sicherheitsinfos
    												0,					// Größe des Stack
    			   								ThreadFunc,				// Threadfunktion
    												(LPVOID)index,		// 32-bit paramter der Threadfunktion übergeben wird
    												0,					// Creation Flags, 0=sofort starten.
    												&dwThreadID[index]);// Id speichern
    	} // end for index
    
    	// Hauptthread gibt nun auch Zeichen aus; Nur 25 dadurch weniger als die erzeugten Threads
    	for (index=0; index<25; index++) {
    		printf("4 ");
    		Sleep(100);
    	} // end for index
    
    	// Auf die Threads warten, bis sie fertig sind
    	WaitForMultipleObjects(	MAX_THREADS,			// Anzahl der Threads, auf die gewartete werden muss
    									hThread,		// Handles der Threads
    									TRUE,			// Für alle warten?
    									INFINITE);		// Wie lange soll gewartet werden, INFINITE = unendlich lange
    
    	// Alle Threads sollten beendet sein
    
    	for (index=0; index<MAX_THREADS; index++)
    		CloseHandle(hThread[index]);
    
    	printf("\nAlle Threads beendet.\n");
    
    } // end main
    
    #define MAX_THREADS 3 //Definiton
    

    Was gibt das denn an? Das 3 Threads verwendet werden?

    DWORD WINAPI ThreadFunc(LPVOID data)
    {
    	// Gibt 50 ein Zeichen mit einer Verzögerung aus
    
    	for (int index=0; index<50; index++) {
    		printf("%d ",(int)data+1);		// Wert ausgeben
    		Sleep(100);						// Verzöger ein bisschen das ganze
    	} // end for index
    
    	// gibt den Wert zurück den du bekommen hast
    	return((DWORD)data);
    

    Ist das die "Definition" von dem Thread?
    Hier müsste ich doch quasi den Teil reinschreiben das ich Daten empfange vom anderen PC und dann müsste ich noch so einen ähnlichen machen wo das was mit Keyboard Input (wahrscheinlich scanf) zu tun hat.

    void main(void)
    {
    
    	HANDLE hThread[MAX_THREADS];			// Handles auf die Threads
    	DWORD  dwThreadID[MAX_THREADS];			// IDs der Threads
    

    Hier wird gesagt das der obendefinierte Thread gestartet wird; aber was soll die Thread ID

    hThread[index] = CreateThread(NULL,							// Sicherheitsinfos
    												0,					// Größe des Stack
    			   								ThreadFunc,				// Threadfunktion
    												(LPVOID)index,		// 32-bit paramter der Threadfunktion übergeben wird
    												0,					// Creation Flags, 0=sofort starten.
    												&dwThreadID[index]);// Id speichern
    

    Wird hier gesagt wie der Thread funktioniert? Das müsste ich doch einfach nur kopieren, oder?

    WaitForMultipleObjects(	MAX_THREADS,			// Anzahl der Threads, auf die gewartete werden muss
    									hThread,		// Handles der Threads
    									TRUE,			// Für alle warten?
    									INFINITE);		// Wie lange soll gewartet werden, INFINITE = unendlich lange
    

    Hier wird das Endekriterium geschlossen, sodass ich dann aus meiner Schleife fliegen würde und das Programm beendet wird.

    Ja dann werde ich jetzt anfangen das mal zu codieren und mal sehen wie viele Fehler ich bekomme. 🙄 Ich werde euch auf dem laufenden halten, da ich nicht denke das es soo einfach ist.



  • Was gibt das denn an? Das 3 Threads verwendet werden?

    Wenn du dir anschaust, wo dieser Name noch verwendet wird, sollte es klar sein.

    aber was soll die Thread ID

    Jeder Thread bekommt halt eine Thread-ID, so wie jeder Prozess eine Prozess-ID kriegt.

    Hier wird das Endekriterium geschlossen, sodass ich dann aus meiner Schleife fliegen würde und das Programm beendet wird.

    Was auch immer das bedeuten mag... Hier wird einfach gewartet, bis alle Threads beendet sind.

    Man sollte aber _beginthread verwenden und nicht CreateThread.



  • Für so was brauchst du keine Threads. Das kannst du auch ganz einfach mit kbhit() + getch() lösen:

    while(eingabe != ESC)
    {
       ...
       //Wenn eine Taste gedrückt wurde
       if(kbhit())
       {
          //Eingabe holen
          eingabe = getch();
          //Sonderfall!
          if(!eingabe)
          {  //bei Sondertasten wie den Funktionstasten wird zuerst eine 0 gelesen und danach ein Code
             //Code der Sondertaste abfangen
             getch();         
          }
       }
       ...
    }
    

Anmelden zum Antworten