Solved

making thread body as member function

Posted on 2001-07-25
8
232 Views
Last Modified: 2013-12-14
In C++ how to create a thread, whose thread body is member function (not static ) of the
class, so that when class object is created, that particular thread should
access only its member variables, which may be the case with as many class
objects created.
0
Comment
Question by:havman56
8 Comments
 
LVL 6

Expert Comment

by:MichaelS
ID: 6320931
I am afraid you can't do it. What is the problem with static functions?
0
 
LVL 7

Expert Comment

by:KangaRoo
ID: 6320942
struct A
{
   void Realwork();
   static void Run(void*)
}

void A::Run(void* parm)
{
   reinterpret_cast<A*>(parm)->Realwork();
}

A object;
makethread(&A::Run, reinterpret_cast<void*>(&A))
0
 
LVL 6

Expert Comment

by:MichaelS
ID: 6320961
>KangaRoo
Actually the question is how to do it without "static"
0
 
LVL 7

Accepted Solution

by:
KangaRoo earned 50 total points
ID: 6320971
make-thread functions generally tke parameters of the form

make_thread(FuncPtrType, void*)
and possible a few others. The function pointer type is usually a C funtion, like void (*FuncPtrType)(void*) or int (*FuncPtrType)(void*). There is no way to fit a non-static funtion pointer into this.
But we can use a static meber and the obvious thing to do is pass the object as the void*. The static can then cast the void* parameter back into an object.

For safety you might consider making the static thread function private and provide a public interface:

class A
{
     void Realwork();
     static void Run(void*)
  public:
     void RunThreaded();
}
void A::Run(void* parm)
{
  reinterpret_cast<A*>(parm)->Realwork();
}

void A::RunThreaded()
{
   makethread(&A::Run, reinterpret_cast<void*>(this));
}

A object;
object.RunThreaded();
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 7

Expert Comment

by:KangaRoo
ID: 6320975
And that is without statics, well, not in the interface. The use of a static member is now a hidden implementation detail :)
0
 
LVL 10

Expert Comment

by:makerp
ID: 6321109
void __cdecl run_thread(void *p)
{
  Class *c = (Class*)p;
  p->run();
  delete r;
}

class Class
{
  void run()
  {
     printf("RUN");
  }
};


the latter on

Class *c = new Class
_beginthread(run_thread,0,(void*)c);

this would/should work on windows compilers
0
 
LVL 4

Expert Comment

by:AssafLavie
ID: 6321142
Consider the following more object oriented approach:

1. Define an interface for performing thread actions:

struct Action
{
     virtual void operator() = 0;
     virtual void ~Action() { };
};

2. Define a general thread creating function and ThreadProc which invoke a functor:

HANDLE CreateThreadObject(Action* pAction)
{
     return CreateThread(0, 0, GeneralThreadProc, pAction, 0, 0);
};
static void GeneralThreadProc(void * prm)
{
     reinterpret_cast<Action*>(prm)->();
};

3. Each time you want to do some task in another thread simply derive from Action:
struct SomeWorkerAction : public Action
{
     void operator()
     {
          MessageBox(0, "This is done on another thread", 0, 0);
          delete this;
     };
};

-- or --

struct SomeWorkerActionWithParams : public Action
{
     string data_;
     SomeWorkerActionWithParams(const string& data) : data_(data) { };
     void operator()
     {
          MessageBox(0, "This is done on another thread", data_.c_str(), 0);
          delete this;
     };
};

And spawn a thread to run it:
     CreateThreadObject(new SomeWorkerAction);
     CreateThreadObject(new SomeWorkerActionWithParams("use this param"));

This approach is a lot nicer. It's easier to pass parameters to the thread and it's also easier to use when implementing more complicated MT applications. (For instance, you can store a queue of Action* and invoke them from a pool of threads.)

btw, the code is just a thought. I didn't compile it or anything so don't be suprised if it has errors. I *do* happen to have a private Thread Pool library which uses a similar idiom.
0
 
LVL 1

Expert Comment

by:xutao
ID: 6329121
I think this is what exactly you want:
http://www.codeproject.com/useritems/callback_adapter.asp

Almost a perfect solution.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now