Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-03-21 18:00:30


On Mar 21, 2007, at 5:20 PM, Yuval Ronen wrote:

> Makes a lot of sense. Makes me wonder why the mutexes in N2094 are not
> movable also.

I actually thought about that. My inclination is to model pthreads
(which also appears to have been the boost inclination). And
pthread_mutex_t does not appear to be a copyable item. And I'm
wanting to be able to implement like this:

class mutex
{
     pthread_mutex_t mut_;
public:
     ...
};

as opposed to:

class mutex
{
     pthread_mutex_t* mut_; // on heap
public:
     ...
};

It appears that a pthread implementation is allowed to point into a
pthread_mutex_t and thus copy/moving it becomes problematic.

To alleviate this, N2094 does make the locks movable. The locks
simply have a pointer to the mutex. The pointer controls (owns) the
locked status of the mutex, not the lifetime of it though. The usual
idiom is to have the mutex at namespace scope, or as a class data
member, and have the lock referring to that mutex "on the stack". So
for the usual idioms, non-copyable, non-movable mutexes do not seem
overly problematic.

In contrast, pthread_t is clearly copyable.

     pthread_t pthread_self();

However the semantics of pthread_t when looked at through a C++ lens
is: sole ownership.

* A pthread_t initialized from pthread_create, must be joined or
detached exactly once.

And a non-guaranteed but common implementation of pthread_t is as
simply a pointer to some opaque struct. Therefore a movable pthread_t
wrapper is quite practical:

class thread
{
     pthread_t thr_;

     thread(const thread&);
     thread& operator=(const thread&);
public:
     thread(thread&& t) : thr_(t.thr_) {t.thr_ = 0;}
     thread& operator=(thread&& t)
     {
          if (joinable()) // is thr_ == 0
          {
              cancel();
              detach(); // sets thr_ = 0
          };
          thr_ = t.thr_;
          t.thr_ = 0;
          return *this;
     }
     ...
};

And this conceptual view appears to be implementable on Windows too
(thanks again Anthony!).

Perhaps if I get the chance to revise N2094 I should include the above
motivation for this choice explicitly (and thanks).

>
>> * N2184::thread separates out the concept of thread identity and
>> thread handle. In boost these are both just boost::thread. The
>> thread::id is copyable. The only thing you can do with it is
>> equality
>> compare it.
>
> I think we might want it to be OutStreamable also. Mainly for
> debugging
> and logging purposes.

Good suggestion, thanks.

-Howard


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