Boost::Thread Boss/Worker Pattern
Von: Georg Gast (schorsch_76@gmx.de) [Profil]
Datum: 23.04.2008 17:16
Message-ID: <funju0$oa6$1@online.de>
Newsgroup: de.comp.lang.iso-c++
Datum: 23.04.2008 17:16
Message-ID: <funju0$oa6$1@online.de>
Newsgroup: de.comp.lang.iso-c++
Hallo NG,
ich bin mir nicht ganz sicher ob es nicht OT ist, aber ich versuch's
trotzdem mal hier ;)
Ich will mich grad ein bischen in "Thread Design Pattern" einarbeiten
und hab das folgende Program.
Ich habe meinen "Boss Thread" welcher 2 Worker Threads startet
(worker1/worker2). Beide zählen einfach eine Variable hoch um Arbeit zu
simulieren.
Ich erwarte eigentlich folgende Ausgabe:
0
1
2
3
4
5
6
7
8
9
20 40
aber ich bekomme
0
1
2
3
4
5
6
7
8
9
20 0
Ich vermute, dass der Lock bei Worker::UpdateDOData(int& data) nicht
wartet, bis der Lock über die condition m_new_command.wait() frei wird.
Ich steh auf dem Schlauch ...
Mein aktuelles System:
Windows Vista x32.
Amd Athlon X2 4400 (2 Kerne)
Boost 1.34.1
MSVC8 SP1
Mit freundlichem Gruß
Georg
P.S.: Danke für die Antworten ;)
----------------------
// BossWorkerThread.cpp
#include <windows.h>
#include <boost/utility.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/condition.hpp>
#include <boost/bind.hpp>
#include <iostream>
class Worker
{
public:
explicit Worker( int x = 42 );
~Worker();
enum Command
{ NO_COMMAND,
TERMINATE,
DO,
MAX_COMMANDS};
void SetCommand(Command command);
void UpdateDOData(int& data);
private:
typedef boost::mutex::scoped_lock lock;
void Run( int x );
Command m_command;
int mi_result;
boost::condition m_new_command;
boost::mutex m_monitor;
boost::thread m_thread; // Achtung MUSS letzter Member sein!
};
Worker::Worker( int x )
: m_command(NO_COMMAND),
mi_result(0),
m_thread( boost::bind( &Worker::Run, this, x ) )
{
}
Worker::~Worker()
{
SetCommand(Worker::TERMINATE);
m_thread.join();
}
void Worker::SetCommand(Command command)
{
lock lk(m_monitor);
m_command = command;
m_new_command.notify_one();
}
void Worker::UpdateDOData(int& data)
{
lock lk(m_monitor);
data = mi_result;
}
void Worker::Run( int x )
{
lock lk(m_monitor);
while (1)
{
while (m_command == NO_COMMAND)
m_new_command.wait(lk);
switch (m_command)
{
case TERMINATE:
return;
break;
case DO:
for (int i = 0; i < x*100000000; ++i)
mi_result = x;
break;
default:
m_command = NO_COMMAND;
break;
}
m_command = NO_COMMAND;
}
}
int main(int argc, char* argv[])
{
int i_result1;
int i_result2;
Worker worker1(20);
Worker worker2(40);
// Start the command "DO" at the worker thread
worker1.SetCommand(Worker::DO);
worker2.SetCommand(Worker::DO);
// do something else
for (int z = 0; z < 10; z++)
std::cout << z << std::endl;
// we need to get the result from the worker thread
worker1.UpdateDOData(i_result1);
worker2.UpdateDOData(i_result2);
std::cout << i_result1 << " " << i_result2 << std::endl;
return 0;
}
----------------------
[ Auf dieses Posting antworten ]Antworten
- James (24.04.2008 10:49)
- Georg Gast (25.04.2008 13:44)
- James (28.04.2008 15:27)
- Michael Hofmann (24.04.2008 09:06)
- Georg Gast (26.04.2008 06:55)
