Boost logo

Boost Users :

From: Roland Schwarz (roland.schwarz_at_[hidden])
Date: 2004-12-12 12:21:45


Peter Dimov wrote:

> Yuval Ronen wrote:
>
> [...]
>
>> If we agree that threads cannot be copied,
>
>
> We don't. More details below.
>
Sorry for jumping in between. But I always was wondering what "copying a
thread"
could mean. Innocently I would expect creating a second instance of the
thread similar
to a "fork" of processes in unix. But I don't think this is what you
have in mind.
Otherwise copying the whole state of a thread is not of much sense
either (thread
needs to be scheduled.) I think noncopyable is a property of a thread,
and the
design simply refelcts this fact, but I might be wrong in this respect
and would like
to hear what I am missing.

>> it means that each thread can be
>> represented by only one thread object. Pass the address of thread
>> objects and compare them, if you really want to. It'll give you the
>> exact same result.
>
>
> The problem with your reasoning is that the thread object may have
> been destroyed. Its lifetime is not tied to the lifetime of the thread.
>
This is true. But where is the problem? Once I have deleted the thread
object (not the thread!) I am not
able to compare it to anything, since the memory is invalid, isn't it?

As I see it, the demand for thread ID's or references mainly come from
the attempt to
communicate with the thread. (Are there really other usages?) So not
having a thread ID
is no drawback at all, since this problem can be solved easily by other
means.

I append a small example showing how a thread can communicate with another,
using a control object with automatic lifetime:
Some remarks
1) from inside the thread I use a tls that holds the communication object
2) from outside I use a wrapper object
3) control of lifetime of this object is tricky, since it must last as
long as both
    communicating threads have agreed to dipose it.

#include <boost/thread.hpp>
#include <boost/bind.hpp>

struct control_impl;
boost::thread_specific_ptr<control_impl*> g_control;

struct control_impl {
    control_impl() : stopped(false), ref(1) {}
    void stop() {
        boost::mutex::scoped_lock lk(monitor);
        stopped = true;
        control_changed.notify_one();
    }
    void wait_until_stopped() {
        boost::mutex::scoped_lock lk(monitor);
        while(!stopped)
            control_changed.wait(lk);
    }
    void release() {
        boost::mutex::scoped_lock lk(monitor);
        if (--ref == 0) {
            lk.unlock();
            delete this;
            g_control.reset(0);
        }
    }
    void addref() {
        boost::mutex::scoped_lock lk(monitor);
        ++ref;
    }
    boost::mutex monitor;
    boost::condition control_changed;
    bool stopped;
    int ref;
};

// the control struct to be used from outside the thread
struct control {
    control() { pimpl = new control_impl; }
    ~control() { pimpl->release(); }
    void stop() {pimpl->stop(); }
    control_impl* pimpl;
};

// the functions to be used from inside the thread
void wait_until_stopped()
{
    (*g_control)->wait_until_stopped();
}
void register_control(control* p)
{
     p->pimpl->addref();
    g_control.reset(new control_impl*(p->pimpl));
}

void release_control()
{
    (*g_control)->release();
}

// the user program
void foo() {
    wait_until_stopped();
}

void run(control* p) {
    register_control(p);
    foo();
    release_control();
}

int main(int argc, char* argv[])
{
    control* pc = new control;
    boost::thread* pt = new boost::thread(boost::bind(run,pc));
    pc->stop();
    delete pc;
    pt->join();
    return 0;
}

In a real implementation of course the user code should not have access to
the control_impl, so it cannot mess with the reference counting.
I admit however that the real question remains: What is a thread object
then at all?
At the momnet its only purpose is to serve as an access point for join.

I think it s worth about thinking about a generalized mechansim that will
allow access of user defined structures from inside and outside a thread.
 
Roland


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