nntp2http.com
Posting
Suche
Optionen
Hilfe & Kontakt

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++
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