Multithreading

09/28/2012 14:42 marykillsjane#1
Guten Tag Leute,
Ich befasse mich seid ca 2 monaten immer mal wd mit c++ und probiere mich dran einfache Programme zu schreiben .
Nun aber wollte ich mich mal am multithreading versuchen da ich eine Schleife programmieren will die solange läuft bis der Benutzer einen button drückt oder Bei der konsole per eingabe die schleife stoppt.
Mir wurde gesagt ich soll eine globale Variable definieren was ich getan habe und dann die schleife in einen Threat packen soll .Mein Problem ist nun aber das ich mir etliche Tuts meist auf Englisch durchgelesen habe aber nicht ganz durchblicke.

Es wäre wirklich nett wenn jmd von euch mir ein beispiel machen würde und mir sagen würde was ich alles für den Threat benötige ( includes,code usw ) ich hoffe jmd kann mir da vlt helfen weil ich wie gesagt bei den Tuts dazu nicht wirklich durchblicke wie das geht.

Edit :Ich Programmiere in c++ und benutze den Dev c++ compiler
09/28/2012 15:05 Dr. Coxxy#2
schmeiss dev c++ aus dem fenster und hol dir microsoft visual c++ express (ich unterstelle dir einfach mal, dass du unter windoof arbeitest).

hier ein beispiel für windoof:
Code:
bool DoRun = true;

DWORD WINAPI MyThread()
{
	for (int i = 1; DoRun; i++)
	{
		Sleep(1000);
		printf("\nDies ist der %d. Durchlauf...", i);
	}
	return 0;
}

int main(int argc, char** argv)
{
	HANDLE MyThreadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MyThread, 0, 0, 0);
	system("PAUSE");
	// Beende Thread
	TerminateThread(MyThreadHandle, 0);
	// Sonstige interessante Befehle:
	// SuspendThread(MyThreadHandle);
	// ResumeThread(MyThreadHandle);

	// Oder: 
	// DoRun = false;
	system("PAUSE");
	return 0;
}
standardisierte threads gibts erst mit c++ 11, musst du mal googlen, wie das genau aussieht.
09/28/2012 15:19 marykillsjane#3
Vielen dank erstmal für die Antwort werde den code heute abend mir nochmal genau angucken und ausprobieren da ich gleich noch weg muss.
Zu der entwicklungsumgebung ich habe visual c++ 2010 express allerdings finde ich es am anfang erstmal übersichtlicher mit dev c++ zu proggen ,da man sich in Visual c++ z.b. bei einer forms anwendung zwar alles an fenstern buttons usw zusammenklicken kann aber im endeffekt weiß ein anfänger wie ich nicht was die ganzen vordefinierten codes alles bewirken.Von daher möchte ich halt erstmal alles selbst an includes code usw schreiben um auch zu verstehen warum usw.
Natürlich kann ich mir in visual c++ 2010 auch einfach ein leeres Projekt anlegen, aber da gibt es dann für mich keinen unterschied ob ich das mit dev c++ oder mit visual mache ^^. Muss erstmal alles richtig lernen dann kann ich mich damit befassen welche entwicklungsumgebung besser für mich geeignet ist.

Edit: Habe noch nie mit der Win Api gearbeitet muss ich ein bestimmtes include noch mit einbinden?
09/28/2012 15:22 Dr. Coxxy#4
leeres projekt machen und visual c++, der standardcompiler von dev c++ ist uralt und die ide an sich ist fürn...
09/28/2012 16:30 MoepMeep#5
Quote:
Originally Posted by marykillsjane View Post
Mir wurde gesagt ich soll eine globale Variable definieren
Nimm einen Stock und schlage diese Person. Feste. Oft.
09/28/2012 18:47 tnd0#6
Quote:
Originally Posted by Dr. Coxxy View Post
schmeiss dev c++ aus dem fenster und hol dir microsoft visual c++ express (ich unterstelle dir einfach mal, dass du unter windoof arbeitest).

hier ein beispiel für windoof:
Code:
bool DoRun = true;

DWORD WINAPI MyThread()
{
	for (int i = 1; DoRun; i++)
	{
		Sleep(1000);
		printf("\nDies ist der %d. Durchlauf...", i);
	}
	return 0;
}

int main(int argc, char** argv)
{
	HANDLE MyThreadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MyThread, 0, 0, 0);
	system("PAUSE");
	// Beende Thread
	TerminateThread(MyThreadHandle, 0);
	// Sonstige interessante Befehle:
	// SuspendThread(MyThreadHandle);
	// ResumeThread(MyThreadHandle);

	// Oder: 
	// DoRun = false;
	system("PAUSE");
	return 0;
}
standardisierte threads gibts erst mit c++ 11, musst du mal googlen, wie das genau aussieht.
SuspendThread, TerminateThread und System() sind 3 funktionen die du niemals verwenden solltest, wenn du keinen guten Grund dafür hast.

Generell sollte man es besser so lösen:

Code:
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

DWORD WINAPI ThreadFunc( int &param )
{
	std::cout << "threadfunc called\n";
	while (param == 0)
	{
		std::cout << "threadloop!\n";
		Sleep(1000);
	}
	std::cout << "thread func end\n";
	return 0;
}


int main ( void )
{
	int iCondition = 0;
	DWORD dwThreadID = 0;
	
	HANDLE hThread = 0;
	hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&ThreadFunc, &iCondition, 0, &dwThreadID);
	
	if (!hThread || !dwThreadID)
		return 1;

	std::cout << "Hit Enter to exit the thread\n";
	getchar();
	iCondition = 1;
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
	std::cout << "Hit Enter to exit the program\n";
	getchar();

	return 0;
}
09/28/2012 21:42 marykillsjane#7
Ich habe nun das Beispiel von Dr.Coxxy genommen da es für mich als Anfänger einfacher zu verstehen war auch wenn es scheinbar wie du sagtest nicht die beste Variante ist.Vielen dank euch allen für die Hilfe das hat sehr gut geklappt mit dem Thread allerdings hätte ich noch ein paar Fragen undzwar :
Durch System("Pause"); wird ja darauf gewartet das der benutzer irgendeine Taste drückt um das Programm zu schließen wie kann ich das ganze nun so gestalten das die schleife im Threat beim drücken von einer von mir festgelegten Taste die schleife stoppt und bei einer anderen festgelegten Taste den Threat erneut startet?
Und die 2te Frage wäre warum werwenden manche std::cout und andere nur cout wo ist der unterschied?

Nochmal Vielen dank euch allen das ihr nem blutigen Anfänger wie mir helft mit dem Threat hat ja schonmal echt klasse geklappt
09/29/2012 01:31 MoepMeep#8
std ist der namespace. Man kann nun entweder
Code:
using namespace std;
funktionsname();
nutzen oder
Code:
std::funktionsname()
Wenn man nicht genau weiß was man macht ist die 2. Variante eher zu empfehlen.

Das Beispiel von Dr.Coxxy ist, wie das meiste was er von sich gibt, kompletter schwachsinn. Das Beispiel von tnd0 ist da doch deutlich besser geeignet.

System("Pause"); solltest du unter keinen umständen verwenden. Wie du den Thread stopst weißt du ja nun. Und wie du einen neuen startest solltest du auch wissen ;) Ich persönlich steuer meine Threads in der Regel über mehrere Zustände.
09/29/2012 01:42 Dr. Coxxy#9
Quote:
Originally Posted by MoepMeep View Post
std ist der namespace. Man kann nun entweder
Code:
using namespace std;
funktionsname();
nutzen oder
Code:
std::funktionsname()
Wenn man nicht genau weiß was man macht ist die 2. Variante eher zu empfehlen.

Das Beispiel von Dr.Coxxy ist, wie das meiste was er von sich gibt, kompletter schwachsinn. Das Beispiel von tnd0 ist da doch deutlich besser geeignet.

System("Pause"); solltest du unter keinen umständen verwenden. Wie du den Thread stopst weißt du ja nun. Und wie du einen neuen startest solltest du auch wissen ;) Ich persönlich steuer meine Threads in der Regel über mehrere Zustände.
Sehr witzig - not.

die sicherheitsbedenken und geschwindigkeitsnachteile von system sind bei diesem beispielcode nun wirklich vollkommen irrelevant.
TerminateThread ist nicht sauber, aber dafür gäbe es ja die DoRun variable, die ich auch eingebaut habe.
tnd0 hat diese laufzeitvariablenmethode verbessert indem er es als parameter in den thread weitergibt, richtig sauber wäre jetzt eine klasse, die den thread komplett abstrahiert, was ein beispiel eines threads aber bei weitem übersteigt.

Der te hat lediglich nach einem beispiel für einen thread gefragt, den ich ihm gegeben habe.
09/29/2012 09:48 MoepMeep#10
Anfänger fragt nach Beispiel - liefern wir ihm unsauberen Dreckscode! Aber hey, man muss C unbedingt for C++ lernen! Man sieht ja, was es dir anscheinend gebracht hat :|
09/29/2012 11:12 marykillsjane#11
Ich versuche mich grad auch am 2ten beispiel was ich daran aber grade nicht verstehe ist warum #define WIN32_LEAN_AND_MEAN definiert wird aber nirgends im weiteren Quelltext benutzt wird .
09/29/2012 11:31 Nightblizard#12
Quote:
Originally Posted by http://msdn.microsoft.com/en-us/library/windows/desktop/aa383745%28v=vs.85%29.aspx


Define WIN32_LEAN_AND_MEAN to exclude APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets.

#define WIN32_LEAN_AND_MEAN
Das sorgt einfach dafür, dass im Windows Header weniger "Müll" miteingebunden wird.
09/29/2012 12:56 dasschild#13
Ich würde nicht die Win32 Api benutzen für MultiThreading. Natürlich funktioniert das alles,nur fehlen wichtige Funktionen fürs MultiThreading. C++ 11 oder boost enthalten OPP Element für Threads. Außerdem sollte man hier auch mal CriticalSections und Mutex erwähnen,da diese sehr wichtig sind wenn mehere Threads an einer Sache arbeiten sollen.
09/29/2012 13:45 .SkyneT.#14
Falls dein Compiler C++0x unterstützt könntest du Threads so verwenden:
Code:
    
   #include <iostream>
   #include <thread>
   #include <chrono>

    void ThreadFunc() 
    {
        std::this_thread::sleep(std::chrono::seconds(1)); 
    }

    int main() 
    {
        std::thread Thread(ThreadFunc); //Start Thread

        Thread.join(); //Wait untill the thread finishes its work
        return 0;
    }
Quote:
Originally Posted by dasschild View Post
Außerdem sollte man hier auch mal CriticalSections und Mutex erwähnen,da diese sehr wichtig sind wenn mehere Threads an einer Sache arbeiten sollen.
Ich denke er wird erstweil auch ohne auskommen.
09/29/2012 15:18 xNopex#15
Quote:
Ich denke er wird erstweil auch ohne auskommen.
Jo. Wenn das Programm mal abstürzt.. Einfach neu starten. Dann gehts wieder die nächstens 100mal. :x