Linux fork within class on heap - c++

What happens when I have the following situation:
class A: holds on to dynamically allocated object B's. It will create and destroy these.
class B: has an execute function called by A. Execute will fork() and the child will use execvp to run another process. BUT, a flag can be set so that the parent will not wait for the child (allows it to run in the background).
My question is, what is fork doing in this case? I know that the child has a complete copy of the process of the parent, but I'm a little confused. So does that mean that the child process has its own object A which holds the B? And what happens if B is not waiting, but A deletes the B?
Here is some sample code. Note that it is simplified from what I am actually doing.
class B;
class A
{
public:
void addAction( const std::string &name )
{
_bq.push( new B( name ) );
}
void doActions( bool wait = true )
{
while ( !_bq.empty() )
{
B* b = _bq.front();
b->execute( wait );
_bq.pop();
delete b;
}
}
~A() { //omitted, but just deletes everything in queue }
private:
std::queue<B*> _bq;
};
class B
{
public:
B( const std::string &name )
{
args.push_back( name.c_str() );
args.push_back( NULL );
}
void execute( bool waitForChild )
{
pid_t pid = fork();
if ( pid != 0 )
{
if (waitForChild)
{
int status;
wait( &status );
// check status...
}
}
else
{
execvp( args[0], const_cast<char**>( &args[0] ) );
// problem
exit( 100 );
}
}
private:
std::vector<char*> args;
};

The child process is completely separate from the parent, and has a complete copy of the parent's variables. When the child executes (calls execve() or one of its relatives), no C++ destructors are executed. However, this has no effect whatsoever on the parent process.
So, there is no interference between the child and the process. It does not matter whether the parent waits for the child or not. As soon as the fork() returns (successfully) to the parent process, the child is running independently and nothing that the parent does to allocated variables will affect the child.
If you really try hard and have shared memory and variables allocated into shared memory via placement new and if the child goes cleaning variables up in shared memory before calling execvp(), or some other similarly far-fetched but not actually impossible scenario, then the child and parent are not completely independent. However, if you were doing something as complex as that, you probably would not be asking the question, either.

When you fork your process, you get an entire copy of the process (although typically it is implemented using copy-on-write), and by "entire copy", I mean an entire copy; including the various pages that have been allocated for that process, so logically there is a whole other copy of the heap and, for each thread, a copy of that thread and its associated stack, so yes, you have two copies of A and B.
A more pressing question, though, when it comes to forking is what happens to threads? Or what happens if you add an "atfork" hook for one of your threads? This one of the few ways that fork+exec can be fairly broken-ish or difficult to use within a UNIX context. It's usually a good idea to solve this once with a library or use popen, rather than trying to solve this multiple times all over the place.

A fork will copy the heap together with the rest of the process data.

Related

C++ delete in daughter thread

It is my understanding that the function called when starting a thread inside an object should not be a class member. The best approach seems to be to launch a friend function, which gets you access back into your object.
In general, the member function (and therefore, the parent thread) that launched the daughter thread can continue or it can return. In every case where I use this technique, I let the launcher method just return to the app in the parent thread that called it; something like Qt threads.
When the daughter thread has finished its work, the final thing it does is return into the friend function which itself returns to something waiting to catch its return (pthread_koin or WaitForSingleEvent) or, if there is no catcher, I guess you'd say it returns to nowhere.
So, here is the question. If there is no catcher for the return from the friend function, that is, the parent thread is not in a member function, can I safely destroy the object that launched the child thread from the friend function?
EDIT --------------------------------------------------------------------------
Obvious from the responses, I need an example. We'll go for Windows. Not that different from Linux. I have left out lots of stuff, the class definition, etc.
Main creates so, a SomeObject on the heap.
Main calls so->run() and goes off to do other stuff.
Run() launches the daughter thread that runs SomeFriend().
SomeFriend() calls so->Worker() (that == so)
Worker() does whatever and returns to SomeFriend().
CAN I DELETE so HERE? i.e. delete that <<<=== the subject of this question.
SomeFriend() returns terminating the daughter thread.
//=================================================================
int main( int argc, char** argv )
{
SomeObject* so = new SomeObject();
so->run();
while(1)
{
DoOtherTasks(); // but don't exit!
}
return 0;
//=================================================================
void SomeObject::run();
(
volatile DWORD ThreadId; // Thread ID
HANDLE threadHandle;
try
{
threadHandle = CreateThread(
NULL, // default security attributes
0, // set stack size: default = 0
(LPTHREAD_START_ROUTINE)(SomeFriend),
(LPVOID*)this, // func args: this
0, // default creation flags
(LPDWORD)(&ThreadId) // ptr to thread identifier
);
}
catch ( ... )
{ throw; }
} // launches the thread and returns.
//=================================================================
void* SomeFriend( void* thisPtr ) // is a friend of SomeObject
{
SomeObject* that ((SomeObject*)thisPtr);
that->Worker();
// HERE IS WHERE THE QUESTION IS TALKING ABOUT
// CAN I DO THIS SAFELY?
delete that;
return (void*)NULL;
}
//=================================================================
void SomeObject::Worker() // remember, this is run in the daughter thread.
{
// whatever
return (void*)NULL;
}
To answer your edited question, yes you can delete that; However, remember that main() or any functions it calls might not have a valid so at any point in its logic after so->run() was called because of the way the thread scheduler may have scheduled the threads.
Think of the thread as "owning" so after you've called so->run(). main() and its stack descendants should never touch so again without guarded logic.
Yes.
Your memory management code should be thread-safe already (or threading would be dangerous to start with!) so the free() itself should be fine. The destruction is fine as well, as long as you keep in mind that nobody else may have a reference to this object as they will be pointing to a destructed object.
The reason that people say that it should not be a class member is that member functions have a typically hidden pointer that's also treated differently on a byte level from other parameters, so you can't just call it as a normal function with an extra parameter. This makes it typically incompatible with the pthread_create and CreateThreadEx functions that have a specific calling convention they want. That's why you have a bouncer static / global / friend function that does this calling convention conversion for you (and probably so transparently that you don't notice it yourself).
There's no inherent reason for not launching a member function as the top-level function in a thread. C++11 handles it just fine:
struct S {
void f();
};
S s;
int main() {
std::thread thr(&S::f, s);
thr.join();
return 0;
}

VC++ 2010: Weird Critical Section error

My program is randomly crashing in a small scenario I can reproduce, but it happens in mlock.c (which is a VC++ runtime file) from ntdll.dll, and I can't see the stack trace. I do know that it happens in one of my thread functions, though.
This is the mlock.c code where the program crashes:
void __cdecl _unlock (
int locknum
)
{
/*
* leave the critical section.
*/
LeaveCriticalSection( _locktable[locknum].lock );
}
The error is "invalid handle specified". If I look at locknum, it's a number larger than _locktable's size, so this makes some sense.
This seems to be related to Critical Section usage. I do use CRITICAL_SECTIONS in my thread, via a CCriticalSection wrapper class and its associated RAII guard, CGuard. Definitions for both here to avoid even more clutter.
This is the thread function that's crashing:
unsigned int __stdcall CPlayBack::timerThread( void * pParams ) {
#ifdef _DEBUG
DRA::CommonCpp::SetThreadName( -1, "CPlayBack::timerThread" );
#endif
CPlayBack * pThis = static_cast<CPlayBack*>( pParams );
bool bContinue = true;
while( bContinue ) {
float m_fActualFrameRate = pThis->m_fFrameRate * pThis->m_fFrameRateMultiplier;
if( m_fActualFrameRate != 0 && pThis->m_bIsPlaying ) {
bContinue = ( ::WaitForSingleObject( pThis->m_hEndThreadEvent, static_cast<DWORD>( 1000.0f / m_fActualFrameRate ) ) == WAIT_TIMEOUT );
CImage img;
if( pThis->m_bIsPlaying && pThis->nextFrame( img ) )
pThis->sendImage( img );
}
else
bContinue = ( ::WaitForSingleObject( pThis->m_hEndThreadEvent, 10 ) == WAIT_TIMEOUT );
}
::GetErrorLoggerInstance()->Log( LOG_TYPE_NOTE, "CPlayBack", "timerThread", "Exiting thread" );
return 0;
}
Where does CCriticalSection come in? Every CImage object contains a CCriticalSection object which it uses through a CGuard RAII lock. Moreover, every CImage contains a CSharedMemory object which implements reference counting. To that end, it contains two CCriticalSection's as well, one for the data and one for the reference counter. A good example of these interactions is best seen in the destructors:
CImage::~CImage() {
CGuard guard(m_csData);
if( m_pSharedMemory != NULL ) {
m_pSharedMemory->decrementUse();
if( !m_pSharedMemory->isBeingUsed() ){
delete m_pSharedMemory;
m_pSharedMemory = NULL;
}
}
m_cProperties.ClearMin();
m_cProperties.ClearMax();
m_cProperties.ClearMode();
}
CSharedMemory::~CSharedMemory() {
CGuard guardUse( m_cs );
if( m_pData && m_bCanDelete ){
delete []m_pData;
}
m_use = 0;
m_pData = NULL;
}
Anyone bumped into this kind of error? Any suggestion?
Edit: I got to see some call stack: the call comes from ~CSharedMemory. So there must be some race condition there
Edit: More CSharedMemory code here
The "invalid handle specified" return code paints a pretty clear picture that your critical section object has been deallocated; assuming of course that it was allocated properly to begin with.
Your RAII class seems like a likely culprit. If you take a step back and think about it, your RAII class violates the Sepration Of Concerns principle, because it has two jobs:
It provides allocate/destroy semantics for the CRITICAL_SECTION
It provides acquire/release semantics for the CRITICAL_SECTION
Most implementations of a CS wrapper I have seen violate the SoC principle in the same way, but it can be problematic. Especially when you have to start passing around instances of the class in order to get to the acquire/release functionality. Consider a simple, contrived example in psudocode:
void WorkerThreadProc(CCriticalSection cs)
{
cs.Enter();
// MAGIC HAPPENS
cs.Leave();
}
int main()
{
CCriticalSection my_cs;
std::vector<NeatStuff> stuff_used_by_multiple_threads;
// Create 3 threads, passing the entry point "WorkerThreadProc"
for( int i = 0; i < 3; ++i )
CreateThread(... &WorkerThreadProc, my_cs);
// Join the 3 threads...
wait();
}
The problem here is CCriticalSection is passed by value, so the destructor is called 4 times. Each time the destructor is called, the CRITICAL_SECTION is deallocated. The first time works fine, but now it's gone.
You could kludge around this problem by passing references or pointers to the critical section class, but then you muddy the semantic waters with ownership issues. What if the thread that "owns" the crit sec dies before the other threads? You could use a shared_ptr, but now nobody really "owns" the critical section, and you have given up a little control in on area in order to gain a little in another area.
The true "fix" for this problem is to seperate concerns. Have one class for allocation & deallocation:
class CCriticalSection : public CRITICAL_SECTION
{
public:
CCriticalSection(){ InitializeCriticalSection(this); }
~CCriticalSection() { DestroyCriticalSection(this); }
};
...and another to handle locking & unlocking...
class CSLock
{
public:
CSLock(CRITICAL_SECTION& cs) : cs_(cs) { EnterCriticalSection(&cs_); }
~CSLock() { LeaveCriticalSection(&cs_); }
private:
CRITICAL_SECTION& cs_;
};
Now you can pass around raw pointers or references to a single CCriticalSection object, possibly const, and have the worker threads instantiate their own CSLocks on it. The CSLock is owned by the thread that created it, which is as it should be, but ownership of the CCriticalSection is clearly retained by some controlling thread; also a good thing.
Make sure Critical Section object is not in #pragma packing 1 (or any non-default packing).
Ensure that no other thread (or same thread) is corrupting the CS object. Run some static analysis tool to check for any buffer overrun problem.
If you have runtime analysis tool, do run it to find the issue.
I decided to adhere to the KISS principle and rock and roll all nite simplify things. I figured I'd replace the CSharedMemoryClass with a std::tr1::shared_ptr<BYTE> and a CCriticalSection which protects it from concurrent access. Both are members of CImage now, and concerns are better separated now, IMHO.
That solved the weird critical section, but now it seems I have a memory leak caused by std::tr1::shared_ptr, you might see me post about it soon... It never ends!

Correct Clean-Up of Parent and Children with Callbacks (C++)

This design problem pops up again and again and I still don't have a nice solution for it. It might turn out to be a design pattern ;) Only, it seems to be very C++ specific (lack of garbage collection). Anyhow, here's the problem:
We have a parent object that keeps references to child objects. The parent's state depends on (some aggregate of) its children's states. In order to be notified of state changes in its children, it passes them a reference to itself. (In another variation it passes them a callback that the children can invoke to notify the parent. This callback is a closure that keeps a reference to the parent.) The application is heavily multi-threaded. Now, this setup is a whole hornet's nest of potential race conditions and dead locks. To understand why, here's a naive implementation:
class Parent {
public:
Parent() {
children_["apple"].reset(new Child("apple", this));
children_["peach"].reset(new Child("peach", this));
}
~Parent() {
}
void ChildDone(const string& child) {
cout << "Child is DONE: " << child << endl;
}
private:
map<string, linked_ptr<Child> > children;
};
class Child {
public:
Child(const string& name, Parent* parent)
: name_(name), parent_(parent), done_(false) {}
Foo(int guess) {
if (guess == 42) done_ = true;
parent->ChildDone(name_);
}
private:
const string name_;
Parent* parent_;
bool done_;
};
Potential issues:
During destruction of the parent, it must be on the lookout for ongoing callbacks from its children. Especially if those callbacks are fired off in a separate thread. If it is not, it might be gone by the time the callback is invoked.
If there are locks in both the parent and the children (very likely in a multi-threaded non-trivial application), locking order becomes an issue: the parent invokes a method on the child, which in turn experiences a state transition and tries to notify the parent: dead-lock.
Adding/Removing children outside the constructor can be an issue if the child tries to notify the parent from its destructor. The parent must be holding a lock in order to modify the map of children, yet the child is attempting a callback on the parent.
I only scratched the surface, but one can think of other potential issues.
What I'm looking for is some advice on how to handle clean destruction of the parent in the face of threads, locks, and dynamic addition/removal of children. If anybody has come up with an elegant solution that is robust under multi-threaded deployment, please share. The keyword here is robust: it's easy to design a structure that comes with some huge caveats (child never calls parent, parent never calls child, no separate thread for callbacks, etc.), the challenge is to put as few restrictions on the programmer as possible.
Often a big part of the problem with multithreading is the failure to properly separate processing (the worker thread i.e. Child) and state.
Locking should be done via thread safe data structures not the threads themselves.
Message queues, state machines and other such tools are intended to allow you to manage such data in a controlled way that is independent of the processes used to update them.
You can almost always rework such a lifetime management problem so that it becomes a (thread safe) data management problem. The parent can be thought of as the owner of the state and the all threads update the state itself.
Reference counting to manage lifetime of objects is a common paradigm also.
If there are locks in both the parent
and the children (very likely in a
multi-threaded non-trivial
application), locking order becomes an
issue: the parent invokes a method on
the child, which in turn experiences a
state transition and tries to notify
the parent: dead-lock.
It's not clear to me why notifying the parent would cause a deadlock unless
the parent lock is held in thread A
thread A is waiting for the child to return a signal via some means
the child is signalling the parent in thread B
the parent when it receives the signal from the child in (3) attempts to obtain its lock
That's a lot of ifs. And it's a naturally problematic design: one thread (A) is holding a lock, and waiting for another thread (B) to do something.
There's no magic solution to avoid this problem - you just have to avoid it. The best answer is probably to not signal back to the parent from a separate thread; or, to distinguish between signals which will or will not be called with the parent lock already held.
During destruction of the parent, it
must be on the lookout for ongoing
callbacks from its children.
Especially if those callbacks are
fired off in a separate thread. If it
is not, it might be gone by the time
the callback is invoked.
The trick here is probably that the children should have a method (perhaps the destructor) which gaurentees that, after it returns, the child will make no further callbacks. When the parent is being destroyed it calls that method for each of its children.
I know you asked for "as few restrictions as possible" but realistically, when working in a multi-threaded environment, you have to have rules to prevent deadlocks and races.
Set a flag to notify the ChildDone function that the object is being deleted and wait for any running client thread to finish before returning from the destructor. This ensures that the object does not become invalid when a thread is executing ChildDone and no further calls to that function is accepted once the destructor is called. (Also see Should destructors be threadsafe?).
// Pseudocode, not compilable C++.
class Parent {
// ....
~Parent() {
mutex_.acquire();
shuttingDown_ = true;
mutex_.release();
foreach (Child child in children_)
child->detachParent();
waitForRunningClientThreadToExit();
}
void ChildDone(const string& child) {
mutex_.acquire();
if (!shuttingDown_)
cout << "Child is DONE: " << child << endl;
mutex_.release();
}
bool volatile shuttingDown_ = false;
Mutex mutex_;
// ....
};
class Child {
// ...
Foo(int guess) {
if (guess == 42) done_ = true;
if (parent)
parent->ChildDone(name_);
}
void detachParent() {
parent = NULL;
}
};
There's a solution with shared_ptr, enable_shared_from_this & weak_ptr trio. Take a look at your code modified:
class Parent : public std::enable_shared_from_this<Parent> {
~Parent()
{
shuttingDown = true;
}
void addChild()
{
Child c{ "some_name", weak_from_this() };
c.foo();
}
void childDone(const std::string& child)
{
if (!shuttingDown)
std::cout << "Child is DONE: " << child << std::endl;
}
std::atomic_bool shuttingDown = false;
struct Child {
std::string name;
std::weak_ptr<Parent> parent;
void foo()
{
//do smth
if (auto shared_parent = parent.lock()) {
shared_parent->childDone(name);
}
}
};
};
This code works but has one serious drawback - the parent object can't be allocated on stack, it always has to be created by making shared_ptr<Parent>. Here's a link to another question about how to get rid of that limitation.

Thread-Safe implementation of an object that deletes itself

I have an object that is called from two different threads and after it was called by both it destroys itself by "delete this".
How do I implement this thread-safe? Thread-safe means that the object never destroys itself exactly one time (it must destroys itself after the second callback).
I created some example code:
class IThreadCallBack
{
virtual void CallBack(int) = 0;
};
class M: public IThreadCallBack
{
private:
bool t1_finished, t2_finished;
public:
M(): t1_finished(false), t2_finished(false)
{
startMyThread(this, 1);
startMyThread(this, 2);
}
void CallBack(int id)
{
if (id == 1)
{
t1_finished = true;
}
else
{
t2_finished = true;
}
if (t1_finished && t2_finished)
{
delete this;
}
}
};
int main(int argc, char **argv) {
M* MObj = new M();
while(true);
}
Obviously I can't use a Mutex as member of the object and lock the delete, because this would also delete the Mutex. On the other hand, if I set a "toBeDeleted"-flag inside a mutex-protected area, where the finised-flag is set, I feel unsure if there are situations possible where the object isnt deleted at all.
Note that the thread-implementation makes sure that the callback method is called exactly one time per thread in any case.
Edit / Update:
What if I change Callback(..) to:
void CallBack(int id)
{
mMutex.Obtain()
if (id == 1)
{
t1_finished = true;
}
else
{
t2_finished = true;
}
bool both_finished = (t1_finished && t2_finished);
mMutex.Release();
if (both_finished)
{
delete this;
}
}
Can this considered to be safe? (with mMutex being a member of the m class?)
I think it is, if I don't access any member after releasing the mutex?!
Use Boost's Smart Pointer. It handles this automatically; your object won't have to delete itself, and it is thread safe.
Edit:
From the code you've posted above, I can't really say, need more info. But you could do it like this: each thread has a shared_ptr object and when the callback is called, you call shared_ptr::reset(). The last reset will delete M. Each shared_ptr could be stored with thread local storeage in each thread. So in essence, each thread is responsible for its own shared_ptr.
Instead of using two separate flags, you could consider setting a counter to the number of threads that you're waiting on and then using interlocked decrement.
Then you can be 100% sure that when the thread counter reaches 0, you're done and should clean up.
For more info on interlocked decrement on Windows, on Linux, and on Mac.
I once implemented something like this that avoided the ickiness and confusion of delete this entirely, by operating in the following way:
Start a thread that is responsible for deleting these sorts of shared objects, which waits on a condition
When the shared object is no longer being used, instead of deleting itself, have it insert itself into a thread-safe queue and signal the condition that the deleter thread is waiting on
When the deleter thread wakes up, it deletes everything in the queue
If your program has an event loop, you can avoid the creation of a separate thread for this by creating an event type that means "delete unused shared objects" and have some persistent object respond to this event in the same way that the deleter thread would in the above example.
I can't imagine that this is possible, especially within the class itself. The problem is two fold:
1) There's no way to notify the outside world not to call the object so the outside world has to be responsible for setting the pointer to 0 after calling "CallBack" iff the pointer was deleted.
2) Once two threads enter this function you are, and forgive my french, absolutely fucked. Calling a function on a deleted object is UB, just imagine what deleting an object while someone is in it results in.
I've never seen "delete this" as anything but an abomination. Doesn't mean it isn't sometimes, on VERY rare conditions, necessary. Problem is that people do it way too much and don't think about the consequences of such a design.
I don't think "to be deleted" is going to work well. It might work for two threads, but what about three? You can't protect the part of code that calls delete because you're deleting the protection (as you state) and because of the UB you'll inevitably cause. So the first goes through, sets the flag and aborts....which of the rest is going to call delete on the way out?
The more robust implementation would be to implement reference counting. For each thread you start, increase a counter; for each callback call decrease the counter and if the counter has reached zero, delete the object. You can lock the counter access, or you could use the Interlocked class to protect the counter access, though in that case you need to be careful with potential race between the first thread finishing and the second starting.
Update: And of course, I completely ignored the fact that this is C++. :-) You should use InterlockExchange to update the counter instead of the C# Interlocked class.

how to write pthread_create on the same function?

Could someone please help with this? I have the following:
// part_1
if (pthread_create(&threadID, NULL, ThreadMain,
(void *) clientSocket) != 0) {
cerr << "Unable to create thread" << endl;
exit(1);
}
// part_2
void *ThreadMain(void *clientSocket) {
pthread_detach(pthread_self());
...
delete (TCPSocket *) clientSocket;
return NULL;
}
I would to have part_2 in part_1 ( I mean without calling TreadMain() function )
thanks for your replies
What if you could do this?
pthread_create() has to create a new stack for the new thread to use. If pthread_create() copied the existing thread's old stack into a separate block of memory to create a new stack, then what would happen to local variables that point to other local variables? The local variables on the new stack would point to the old stack. When the thread using the old stack (the one that called pthread_create()) returns or overwrites them, those variables start pointing to invalid data.
But what about fork()? Why doesn't fork() take a function pointer like pthread_create()? Well, unlike pthread_create(), the new thread of execution created by fork() doesn't have to live in the same address space as the old thread of execution, because they are in separate processes. fork() clones the parent process's virtual address space, stack, heap, and all. The child process's stack variables have the same virtual addresses as the corresponding variables in the parent process. So all of the pointers in the new child process continue to be valid*, no matter what the old parent process does with the memory.
* Nitpicker's corner: excluding pointers that were invalid to begin with, as well as memory that is deliberately shared
If all you want to do is simply move the function for part2 inside part1, you can create a local class inside of part1, with a static member function...
class LocalFunctor
{
public:
static void *ThreadFunc(void* clientSocket)
{
pthread_detach(pthread_self());
...
delete (TCPSocket *) clientSocket;
return NULL;
}
};
then call LocalFunctor::ThreadFunc within pthread_create
pthread_create(&threadID, NULL, LocalFunctor::ThreadFunc,(void *) clientSocket)
If you're going to do this more than once, look at boost::thread or wrap this up inside a template helper class.
You could get an Apple Macintosh computer with OS 10.6 and start programming with Grand Central Dispatch. Apple added some new C compiler features that do almost exactly what you seem to want. They're called Blocks.