Boost logo

Boost :

From: Beman Dawes (bdawes_at_[hidden])
Date: 2001-06-27 08:44:08


At 10:06 PM 6/26/2001, Greg Colvin wrote:

>> >Imagine a server that sits in a loop spawning threads to handle
>> >incoming requests. When the request is handled the thread is
>> >done, at which time any resources used by the thread need to be
>> >released, pronto. So you need to create thread objects that will
>> >magically disappear when they are done running.
>> >
>> >I started out to write a function to do this, and quickly began
>> >to think it would be much easier for the thread class to provide
>> >a utility for the purpose that returns shared_ptr<thread>.
>>
>> Isn't that what detach() is for? So after detach() has been called on
a
>> thread object, the underlying thread of execution is no long related to

>the
>> thread object, and delete can be called on the thread object
immediately.
>
>So to do what I want I have to write
>
> thread* temp = new thread(handler);
> temp.detach();
> delete temp;
>
>whereas with native code I would just do
>
> CreateThread(0,0,handler,0,0,0);
>
>or in java
>
> new Thread(handler);

[Aside: a number of common needs like the above have been identified in
this discussion. I'll try to collect them so we can later show how our
final solution would solve them.]

Here is Bill's possible thread class:

>It would simply be this:
>
> class thread : boost::noncopyable
> {
> public:
> thread(const detail::threadfunc& func);
> ~thread();
>
> bool is_alive() const;
> bool join();
> bool detach();
>
> static void join_all(); // This may be pointless!?
> static void sleep(const xtime& xt);
> static void yield();
> };
>
>The destructor will call join() unless a call to detach() had been
>previously made.

Back to your example. Here are some possibilities:

1) new thread(handler).detach();

2) new thread(handler); // change dtor semantics: if (is_alive())
detach();

3) new thread(handler, detach_option); // add ctor option

4) new detached_thread(handler); // add 2nd thread class

I expect some of these are much better than others.

>A harder example is keeping a list of all the running threads.

Each time a thread is created, you stuff a pointer to it in a std::list,
and the handler function is passed the iterator for the list entry. Before
it exits, the handler function must call a function, passing the iterator
as an argument, which erases the list element.

>When I try actually writing such code I get confused real fast,
>trying to be sure that the thread object has just the lifetime
>I want.

Seems like the worker function must cooperate for some uses, unless you are
willing to poll is_alive() periodically.

--Beman


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk