Hi All,

this is my first query after joining the forum.

I would like to know following points:

1. If I can create threads in constructor

2. If yes, can I use the same object / instance (which created this thread)in this thread to call other methods of the class

3. I want to keep this thread as long as the class is running, how can I do that?

Pls help me here....

Recommended Answers

All 9 Replies

1st question: Linux / windows?

if you are working in Windows, I am sure there will be similar method call like pthreads.

Following examples are given using pthread.


Answer of Q 1) You can create a thread from the constructor but why do you want to create a thread from constructor, its not a good practice.

Its funny that i just replied someone with his thread question, here is the sample code which i written for him, it may be helpful for you too.

/*
 * thread.h
 *
 *  Created on: Nov 8, 2010
 */

#ifndef THREAD_H_
#define THREAD_H_

#include <pthread.h>

class PThread{
	pthread_t thread_id;

public:
	PThread(){
		pthread_create( &thread_id, NULL, EntryPoint, (void *)this);
	}

	void Start(){
		//pthread_create( &thread_id, NULL, EntryPoint, (void *)this);
	}
	static void *EntryPoint(void *thread){
		PThread *self = static_cast<PThread *>(thread);

		self->Run();
	}
	virtual void Run() = 0;  //It is a virtual method, have fun!!
};


class JobSchedular: public PThread{
	virtual void Run(){
		for(int i = 1; i <= 10; i++){
			cout << "scheduling job" << endl;
			sleep(1);
		}
	}
};


#endif /* THREAD_H_ */
JobSchedular th1;

//	th1.Start(); YOUR case constructor starts it, but not a good practice!!

Answer of Q 2) Yes ofcourse

//look i have called Run method
self->Run();

Answer of Q 3) As long as your Run method is running :) your thread will run, but if your process terminate, your thread will terminate too.

there is a method in Pthread, pthread_join which you can use/call from main, if you call this method, then calling point will wait unless this thread has finished and joined.

pthread_join( thread_id, NULL);

Hi alwayslearning0, thanks for reply. OS is Solaris. I am working on a project where I need to execute a method once every day. And this i want to do in parallel to other executions as this method will not affect / depend on other parts. So I do not know how can I instantiate this method. So I thought creating a thread from constructor that runs for life time of the class would be good Idea.

Do you see any other alternative for this.

Hi again, thanks for quick reply. Yeah I understand the point of using cronjobs. But was look at other alternatives of including this into code itself. If you have alternative suggestion it would be appreciated.

Thanks anyway.

It would be easier to create the thread outside the class, in main() for example, and then instantiate the c++ class inside the thread function. I don't know how to create a thread in *nix so you will have to figure that one out yourself. But here is the general idea.

class MyClass
{
   // blabla
};

int myThreadFunction(void* parameter)
{
   MyClass c;
   // do things with this class
}

int main()
{
   // create the thread here
}

What is your requirement again? Can you give little more info: Like what your thread wants to do?

Lets say you have a big program running and it has some data in memory. If you want to run a scheduled job on those data(in memory) then you need to write a thread, start the thread from the main(), look the above example.

But if your job is not shared (that means the data stored in some db, or file) with your main project, then you can write a stand alone program to take care of the job which can be run using cron jobs.

If you give me more info, then i might be able to give you more specific answers.

Hi alwayslearning0, my requirement is the second option what you mentioned above (that means the data stored in some db, or file). But I was trying to see if any parts of code can be re-used. During this process I am struck at point where to trigger this thread that can do the job.

I think that Boost.Thread is by far the easiest solution (I'm not sure how well it is usable on Solaris, but I presume it is alright.. at leas the latest version).

Here is how I would do it:

#include <boost/thread.hpp>

class MyClass {
  //blablabla
  //need to provide a copy-constructor and assignment operator.
  //and make it callable, with operator () :
  public:
    void operator()() {
      //do your stuff here...
    };
};

int main() {

  while (true) {
    boost::thread daily_processing(MyClass(/* some params */));
    //...
    //do all the other stuff your program does.
    //...
    //check if the daily processing is done, if not, join it to the main thread.
    if(daily_processing.joinable()) 
      daily_processing.join();
  };
  
};

In the above example, the object of class MyClass will be copied once into the internal storage of the boost::thread object. If MyClass is large or a singleton or you want it to persist through the entire application's lifetime (not just for the life-time of the thread), then here is an alternative:

#include <boost/thread.hpp>

class MyClass {
  //blablabla
  //no need to provide a copy-constructor or assignment operator (although, you should either disable them (boost::noncopyable) or provide them).
  //provide a callable nested functor:
  public:
    struct daily_process_functor {
      MyClass& parent;
      daily_process_functor(MyClass& aParent) : parent(aParent) { };
      daily_process_functor(const daily_process_functor& aObj) : parent(aObj.parent) { };
      void operator()() {
        //do your stuff here... using parent.methodName(); 
        //or.. you also have access to private members of MyClass to do everything here.
      };
    };
};

int main() {

  MyClass data; //you have a persistent object "data".
  while (true) {
    boost::thread daily_processing(MyClass::daily_process_functor(data));
    //...
    //do all the other stuff your program does.
    //...
    //check if the daily processing is done, if not, join it to the main thread.
    if(daily_processing.joinable()) 
      daily_processing.join();
  };
  
};

The above is essentially how I do it, and I recommend it to you. If Boost.Thread does not work for you or you can't get Boost at all, then it isn't hard to adapt the above scheme to whatever is compatible to your setup (you can easily make a class that is very similar to Boost.thread by following the layout of the class).

thank you all for providing valuable information. I really got lot of information apart from what I needed.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.