Boost logo

Boost Users :

From: Andrew Holden (aholden_at_[hidden])
Date: 2007-12-18 10:28:37


boost-users-bounces_at_[hidden] <> wrote:
> I haven't been able to find any clear explanation about this,
> so here it goes:
>
> I'm coding a multithreaded program using pthreads. The
> general behaviour is this:
>
> -A function starts.
> -The function creates a shared pointer "OBJ".
> -The function creates a Thread, passing "OBJ" as the
> parameter (having to cast it as void*).
> -The thread starts, getting a (void*) param which is casted
> back to "OBJ" (shared pointer type).
> -The function ends, and therefore its "OBJ" goes out of scope.
> -The thread" ends, so its "OBJ" goes out of scope too.
> (of course, the thread could at times end before the function instead)
>
> I'm afraid that the shared pointer does not behave well due
> to those nasty void* casts... maybe trying to delete twice the object.
> What's the proper way of coding this? Weak pointers maybe?
>
> Thanks a lot for any help.

The first problem I see is that a boost::shared_ptr is not the same size
as a void*. The believe the cast would slice off the pointer to the
reference count. I would try something like the following (untested):

//Notice that we are passing the shared pointer by value. I
//consider this important because we are about to abuse it.
void Spawn_thread (boost::shared_ptr <whatever> value)
{
        pthread_t thread;
        pthread_attr_t attr;

        //Notice that I'm passing a raw pointer to the shared pointer.
        if (!pthread_create (&thread, &attr, &Thread_main, &value))
        {
                //Wait for the new thread to copy its parameter into a
                //local variable
                Wait_for_signal();
        }
        else
        {
                //Error handling
        }
}

void *Thread_main (void *arg)
{
        //Dereference the argument (to get back the shared pointer),
copy
        //it into a local shared pointer and allow the main thread to
proceed

        boost::shared_ptr <whatever> parameter = *reinterpret_cast
<boost::shared_ptr <whatever> *> (arg);

        //Remove any temptation to use a value that is about to become
undefined.

        arg = NULL;

        //Now that we have copied the shared pointer, we can allow
Wait_for_signal() to return.

        Signal_main_thread();

        //Your code goes here. Under NO circumstances are you to call
        //pthread_exit(). You must allow Thread_main() to return
        //normally if you want to avoid memory leaks.
}

Wait_for_signal and Signal_main_thread may need some explanation. I'm
not sure of the best way to implement them with pthreads. In Windows, I
would just use an event, but I remember reading that pthreads doesn't
have one. You could use a semaphore or a simple spin lock to implement
them. I hate to say it, but you'll have to get creative if there is
even the slightest chance of multiple threads calling Spawn_thread at
the same time.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net