|
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