Boost logo

Boost Users :

From: Martin Pasdzierny (martin_at_[hidden])
Date: 2004-12-12 07:24:31


Yuval Ronen wrote:
>>>However, thread1, as returned by create_thread, and the thread_ref
>>>returned by current_thread inside the newly spawned thread will indeed
>>>be equivalent. They will not only compare equal, but will be
>>>interchangeable in every way.
>>
>>Very good.
>>
>>Do You plan to change the current implementation ( would be a partial
>
> re-implementation) ?
>
> How about comparing address of thread objects (using the current design)?
> Will that satisfy your needs?

It would, as long as I have the threads address available from *inside* the thread.
But to my understanding boost::thread::thread() does *not* return a globally addressable object.

At the end of this posting You will find a compilable but dangerously simplyfied example to demontrate my needs.
Its main idea is to make the global boost::thread objects address available through a thread_specific_pointer object.

The used approach is far from *elegant* but I didn't find something better.

(Having the threads id available from *inside* a static-like call to boost::thread::thread().id()
as well as from *outside* by the threads objects method 'id' would simplify the example ...)

> As I explained some messages ago, if threads are noncopyable, you can use
> address of thread objects as a comparable thread_id, while not needing the
> implementation details (such the Windows handles) at all. If you use this,
> you need to be careful not to create a thread using the no-parameters
> constructor, becuase it will entirely ruin my philosophy...
???

// g++ -pthread -W -Wall -lboost_thread-gcc-mt thread_pointer_test.cpp -o thread_pointer_test
#include <iostream>
#include <set>
#include "boost/thread.hpp"
#include "boost/thread/tss.hpp"
#include "boost/thread/xtime.hpp"

boost::thread_specific_ptr<boost::thread*> current_thread_;

std::set<boost::thread*> some_global_thread_pointers ;

void wait(int sec) {
   boost::xtime wait_until;
   boost::xtime_get(&wait_until, boost::TIME_UTC);
   wait_until.sec += sec;
   boost::thread::sleep(wait_until);
}

void some_global_func() {
   if(current_thread_.get()) {
     std::cout << "\nsome_global_func uses current_thread_:" << *current_thread_ << std::flush;
     // in real life some_global_thread_pointers must be protected with mutexes
     std::set<boost::thread*>::iterator it = some_global_thread_pointers.find(*current_thread_);
     if(it != some_global_thread_pointers.end())
       std::cout << "\nsome_global_func found myself in some_global_thread_pointers" << std::flush;
     else
       std::cout << "\nsome_global_func did not find myself in some_global_thread_pointers" << std::flush;
   }
}

struct thread_functor {
   boost::thread** this_pointer_;
   thread_functor(boost::thread** address_of_this) : this_pointer_(address_of_this) { }
   void operator()() {
     wait(1);
     std::cout << "\nthis_pointer_:" << this_pointer_;
     std::cout << "\n*this_pointer_:" << *this_pointer_;
     if(this_pointer_ && *this_pointer_) {
       std::cout << "\ninitializing current_thread_ ..." << std::flush;
       current_thread_.reset(this_pointer_);
     } else std::cout << "\nfailed to initialize current_thread_" << std::flush;
     wait(1);
     // call other functions etc.
     some_global_func();
     std::cout << "\nmy_thread ends" << std::flush;
     current_thread_.release(); // I'm not really happy with the 'assymetric' need to call this method ;-(
   }
};

int main(int argc, char** argv) {
   boost::thread *my_thread_1(0),*my_thread_2(0);
   thread_functor my_functor_1(&my_thread_1),my_functor_2(&my_thread_2);
   my_thread_1 = new boost::thread(my_functor_1);
   std::cout << "\n&my_thread_1:" << &my_thread_1 << std::flush;
   std::cout << "\nmy_thread_1:" << my_thread_1 << std::flush;
   my_thread_2 = new boost::thread(my_functor_2);
   std::cout << "\n&my_thread_2:" << &my_thread_2 << std::flush;
   std::cout << "\nmy_thread_2:" << my_thread_2 << std::flush;
   wait(2);
   some_global_thread_pointers.insert(my_thread_1);
   std::cout << "\ninserted my_thread_1 into some_global_thread_pointers, waiting for my_threads to join" << std::flush;
   my_thread_1->join();
   my_thread_2->join();
   delete my_thread_1;
   delete my_thread_2;
   std::cout << "\n...bye\n" << std::flush;
}


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