Multitasking
-
Grüße

Ich wüsste gern wie ich Multitasking-Programme schreiben kann.
z.B.:Eine Zeitzählfunktion läuft neben dem Hauptprogramm.
Wenn man dann auf einen Button im Fenster klickt wird die gezählte Zeit angezeigt.
(also auch Variablenübertragung)Kann mir da einer helfen?
Mfg
-
ups des ist gar net so einfach:
Wenns "echtes" multitasking sein soll kommst du um POSIX-threads leider nicht
herum und dann variablen zwischen den einzelnen (leight-weight-)prozessen
auszutauschen ist gar net so einfach. Unter Linux/Unix kannst du auch den
forkbefehl verwenden um multitasking zu implementieren.

-
Naja, was heißt es ist nicht einfach? Im Prinzip ist es sehr einfach.
Welche GUI-API benutzt du denn? MFC, Win32, Qt, wxWidgets oder was? Die haben alle Multithreading im Angebot.
Ansonst gibts halt noch boost::thread. Mußt du natürlich die Boost Libs haben.
Hier ist ein dt. Tut von mir: http://www.kharchi.de/threads.html
-
und wie tauschen die einzelnen threads daten aus (pipe,shared memory,usw)
mit der boost-library, wie wird der daten-austausch synchroniesiert? ist des
auch einfach?btw. wenn man Qt kommerziell verwendet kommen nicht
ganz unmaßgebliche license-gebühren auf einen zu
-
Lies dir am besten mal die Doku von Boost dazu durch.
Hab ich heute auch. Anscheinend tut
man einfach die Entsprechenden klassen mit einem Mutex
'bestücken', und erzeugt in den Memberfunktionen
jeweils locking Objekte, die das Objekt nach
dem Verlassen der Funktion automatisch wieder
freigeben. Somit wird verhindert das man vergisst
ein Objekt wieder zu unlocken.
-
DrakoXP schrieb:
Ich wüsste gern wie ich Multitasking-Programme schreiben kann.
z.B.:Eine Zeitzählfunktion läuft neben dem Hauptprogramm.
Wenn man dann auf einen Button im Fenster klickt wird die gezählte Zeit angezeigt.
(also auch Variablenübertragung)boost.thread ist schon mal ein guter Tipp. Erstens ist es plattform-übergreifend und zweitens einfacher, als sich z.B. mit einer Win-API herumzuschlagen.
Mal angenommen, da ist eine Zähler-Klasse, die im einfachsten Fall etwa so aussieht:
#include <boost/bind.hpp> #include <boost/thread.hpp> class Zaehler { public: Zaehler() : m_isRunning( true ) , m_count( 0 ) , m_thread( boost::bind( &Zaehler::Run, this ) ) // compiler warning ignorieren, wenn m_thread letztes Member {} ~Zaehler() { m_isRunning = false; // Beenden des Threads ist notwendig m_thread.join(); } int Count() const { return m_count; } private: void Run() // hier drin rennt mein Thread { for(; m_isRunning; ++m_count ) { // mache hier was auch immer // z.B. 1 Sekunde schlafen (sleep) } } // -- Member bool m_isRunning; int m_count; boost::thread m_thread; // MUSS letztes Member sein };dann trägt 'Zaehler' einen Member m_thread, der die Methode Zaehler::Run in einem eigenen Thread laufen läßt. Wie Du siehst funktioniert das mit der Datenübertragung hier einfach so, dass beide Threads - also der Haupt-Thread und der Thread von m_thread einfach auf die Member des identischen Objekts zugreifen.
Das geht hier nur deshalb gut, weil immer nur einer von beiden schreibt und beide Variablen (m_count, m_isRunning) einfache Datentypen sind, bei denen das Lesen nicht durch einen Threadwechsel unterbrochen wird (so hoffe ich
)Beim Übersetzen bekommt man eine Compiler-Warning (zu Recht), da this als Parameter für einen der Member benutzt wird. Im Konstruktor von boost::thread rennt dieser gleich los und zu diesem Zeitpunkt müssen alle Member der Klasse initialisiert sein; daher muss m_thread das letzte Member sein.
Ein Objekt dieser Klasse kannst Du als Member eines Windows oder Dialoges setzen. Der Thread startet sobald das Window oder Dialog-Objekt angelegt ist. Danach kann man dann in einer On-Button-Klick-Methode einfach den Zähler-Stand mit Count() abfragen.
Wird die Klasse anspruchsvoller, so solltest Du die Member mit einem Mutex schützen. Dazu fügt man ein Mutex als Member hinzu:
// -- Member mutable boost::mutex m_guard;den macht man am besten gleich mutable, damit man auch const-Methoden schützen kann.
So wird dann Count angepasst:int Count() const { boost::mutex::scoped_lock lock( m_guard ); return m_count; }und damit das ganze überhaupt Sinn macht, darf auch der eigenen Thread nur an m_count bzw. weitere (Nutz-)Member ran, wenn sonst keiner die Hand drauf hat - also das Mutex es zulässt:
void Run() { for(; m_isRunning;) { boost::mutex::scoped_lock lock( m_guard ); // hier immer noch irgendwas tun, .. ++m_count; // auf 'm_count' exclusiv schreiben } }boost ist

Gruß
Werner
-
was spricht dagegen, in der Run() - funktion ein lokale thread-instanz zu erstellen, die eine zweite funktion (DoWork() o.ä.) in einem neuen thread startet?
-
'''m''' schrieb:
was spricht dagegen, in der Run() - funktion ein lokale thread-instanz zu erstellen, die eine zweite funktion (DoWork() o.ä.) in einem neuen thread startet?
Dagegen spricht, dass von dieser lokalen Instanz am Ende von Run() der Destruktor aufgerufen wird. Es gibt zwei Möglichkeiten:
1.) Warte in Run() bis der Thread in DoWork() fertig ist; dann ist der Thread unnötig, man kann DoWork direkt aufrufen.
2.) Warte nicht, dann wird der Destruktor von boost::thread gerufen, der z.B. in Windows zu einem CloseHandle auf den Thread-Handle führt; bedeutet Freigabe der Ressourcen bei laufendem Thread - das kann eigentlich nur schiefgehen.Preisfrage: Was würde dafür sprechen, wie ist Deine Idee?
Gruß
Werner
-
ich hatte eigentlich 2. im sinn. aber wenn die ressourcen freigegeben werden, ist natürlich blöd.
ich habe da~thread();
Effects: Destroys *this. The actual thread of execution may continue to execute after the thread object has been destroyed.
wohl was missverstanden.
