The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Threading question: function or method?

I am writng a multi-threading code.
I have a class that start a thread via _begintread().
The functionality change ass needed.

I thought of two options:
1. Register - pass the address of a static function to
  the class. The user can register his favorite function.
2. Inherit - This requires the user to derive his own class and to implement his verstion of the thread function and the function to run the thread.

class thread
{
virtual runthread() // call thread via beginthread
static thread()
bool command; // run/stop thread
bool status; // is thread running or stopped
}

The final issue is that the function has to commuincate with the class by flags, see code above.

Which way is better in your view?
Dale Lawrence
Tuesday, September 05, 2006
 
 
The inependant running function receive a parameter of type Thread*, cast-able to Thread*, or a reference and use it to communicate with that Thread.

The Thread class could even provide both features (function pointer with parameter and inheritance).

I would prefer not to inherit if I do not want to extend Thread feature. IMNSHO, inheriting to give this running member function is an abuse of inheritance.

My (business) class is not a thread but could have an associated running function.

Of course comes the issue to have access from this running function to my business classes.

That could be a second parameter.
Val Send private email
Tuesday, September 05, 2006
 
 
> Register or Inherit?

If it's for OO C++ code then I'd prefer inherit instead of registering a static method.

Given inheritance I'd prefer something like as follows, because it means that client code needs to implement the IThreadProc interface instead of deriving from the Thread class; the IThreadProc interface is light-weight, private, and pure abstract, so it's easier to inherit from.

//IThreadProc interface implemented by the client class which uses Thread
class IThreadProc;

//client passes its IThreadProc interface to the constructor of the Thread instance
class Thread
{
public:
  Thread(IThreadProc& clientThreadProc);
  void start();
  void stop();
  bool isRunning();
private:
  static void staticThreadProc();
};

class IThreadProc
{
private:
  virtual void run() = 0;
  friend class Thread;
};
Christopher Wells Send private email
Tuesday, September 05, 2006
 
 
Create a Command class with a virutal method like performAction.

Derive from Command and implement the functionality you want to happen in thread context. The Command object can be completely separate from your domain logic if you wish.

At this point you have several options.

You can have an actor which is a thread with a queue. You can queue up commands to the actor and the actor will block on the queue procesing Commands in the thread context.

Or you can create a thread and pass the command as a void* to the thread start callback. Cast the void* to a Command* and call performAction.
son of parnas
Tuesday, September 05, 2006
 
 
Christopher Wells' method is just perfect IMO, since it decouples threading implementation (create/destroy/manage/queuing/etc...) from code related to the specific thread you want to create.
antonio
Thursday, September 07, 2006
 
 
Christopher's code sharpened my insight of the problem.

I came up with the following idea:

class ConcreteThread:public IThread
{
static void staticThreadProc(); // concrete proc
}

class IThread
{
public:
 virtual RunThread();
 virtual StopThread();
 virtual bool IsThreadRunning();

private:
 ProcessControl *m_PControl;
 static void staticThreadProc();
}

class ProcessControl:public ICommand, IState
{
bool m_Command;
bool m_State;
}

class ICommand
{
Run()
Stop()
IsRunning()
}

class IState
{
Running();
Stopping();
bool GetCommand();
}

and here how to use it... I might ommit few details.
IThread *p = new ConcreteThread;
// beginthead if state flag is zero
// pass IState to the thread
p->RunThread();

ConcreteThread::staticThreadProc() // concrete proc
{
 while (pState->GetCommand)
 {
 }
 // exit
 pState->Stopping();
 return;
}
Dale Lawrence
Thursday, September 07, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz