Click here to Skip to main content
15,884,629 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Is it safe to create threads in constructor.

All threads uses data of the object in which they are created.
I am creating threads after initializing all the member variables.
MyConstructor()
{

//////INITIALIZATION OF MEMBER VARIABLES START
.
.
.
.
.
.
.

//////INITIALIZATION OF MEMBER VARIABLES ENDS


CreateThread( NULL, 0, myThreadProc, this,0,NULL );


}
Posted
Updated 16-Jun-11 22:39pm
v2

It would be unsafe to use virtual functions in C++ constructor (never try it). If you don't do this big mistake, why not? I would only recommend to start the thread later, not in constructor. This is not the rule, just easier to design your code properly.

—SA
 
Share this answer
 
Comments
CPallini 17-Jun-11 7:51am    
Good point. 5.
Sergey Alexandrovich Kryukov 17-Jun-11 13:37pm    
Thank you.
--SA
I would say its perfectly fine to do so... I've had to create manager classes that start multiple threads and the constructor is where it makes most sense to do so. In a lot of cases, if your thread fails to start, you're going to end the application anyway.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 17-Jun-11 13:38pm    
True, a 5.
--SA
Albert Holguin 17-Jun-11 13:40pm    
thanks SA
You may do that if you can safely handle (in your object logic) possible CreateThread failures.
 
Share this answer
 
Comments
Stefan_Lang 17-Jun-11 7:35am    
In other words: No. If *he* has to take care of the safety then this means he can *not* 'safely' call CreateThread. ;)
CPallini 17-Jun-11 7:49am    
What 'safety'? CreateThread is an API function. You may store its return value and handle errors at any point of the object's lifecycle.
As Sergey pointed out correctly, only the neatness of the design may suffer from such a choice.
Stefan_Lang 17-Jun-11 8:10am    
Granted - that was just my built-in Security System answering before getting around to make a sanity check. ;) 'In general' I consider it unsafe to call other functions in a constructor, specifically if it is provided by MS - I've had some bad experiences related to migration to another OS version...

But you're right, CreateThread is safe enough, even MS shouldn't mess it up too badly. :-)
Sergey Alexandrovich Kryukov 17-Jun-11 13:46pm    
In other words, "yes". There is nothing unsafe here. Do you think constructors never throw exceptions? It would be not realistic. Code can throw exception and be perfectly safe.
Wrong conclusion.
--SA
Stefan_Lang 20-Jun-11 4:32am    
See my responses to C. Pallini - It wasn't a wrong conclusion, just a wrong assumption (i. e. that excepted instantiations would return a non-null pointer).

And with respect to CreateThread being safe - while I haven't noticed any problem with it yet, I've experienced so many very nasty problems with other, presumably 'safe' system functions on Windows that I don't trust any of them. Ever! Ok, maybe when Linus Thorwald open-sources Windows... ;)
The problem with constructors is that - without a return value - you have no easy way to pass an error state, and you may not throw an exception. So, as C. Pallini already pointed out, you have to deal with all possible causes of failure right within the constructor code.

This may become even trickier when your class contains virtual methods! As SAKryokov pointed out, it is not safe to call virtual methods in a constructor.

To answer your question: No. In general it is not safe. As a rule of thumb, the less functions you call in a constructor, the better! You can do it if you know what you're doing and are capable to deal with all error cases, but it's much safer to do this in a separate function.
 
Share this answer
 
Comments
CPallini 17-Jun-11 7:45am    
You may throw in constructors, of course. See for instance: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.8
Stefan_Lang 17-Jun-11 8:04am    
Well, you can, but I don't consider that a good idea:
class MyBad {
public:
MyBad() { throw(); }
};
class MyCompromised {
char p;
MyBad bad;
public:
MyCompromised() {
p = 0;
}
~MyCompromised() {
if (p)
delete [] p;
}
}
};
int main() {
MyCompromised* mc = 0;
try {
mc = new MyCompromised; // <-- throws before executing constructor body
}
catch/* whatever */ {
delete mc; // <-- crash!
}
}
The only 'bad' thing the developer of 'MyCompromised' did is use a member of type 'MyBad'. He can't prevent this, even if he knows that MyBad may throw exceptions, because the exception occurs before the constructor body is even executed. And he may not even know of these exceptions to start with...
CPallini 17-Jun-11 8:11am    
As the linked page shows, it is the proper way to handle ctor failure (you should signal the object is not ptoperly initialized). As about your example, you know, deleting a NULL pointer is harmless.
Stefan_Lang 17-Jun-11 8:13am    
The point is, p will not be initialized! So the call to delete mc will try to delete [] mc.p which is not initialized to 0!
CPallini 17-Jun-11 8:40am    
Nope, beacuse mc is never deleted (is NULL after all). The following code (basically yours with some fixes for syntax errors) runs happily on my system:
class MyBad {
public:

MyBad() { throw "failure"; }
};
class MyCompromised {
char *p;
MyBad bad;
public:
MyCompromised() {
p = 0;
}
~MyCompromised() {
if (p)
delete [] p;
}
};
int main() {
MyCompromised* mc = 0;
try {
mc = new MyCompromised(); // <-- throws before executing constructor body
}
catch(...) {
delete mc; // <-- crash!
}
cout << "hi" << endl;
}

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900