Le 13/06/13 07:16, Anthony Foiani a
écrit :
Greetings.
I have a class that wraps a boost::thread object, and I would like to
specify certain thread attributes at construction time.
My first attempt looked basically like this:
struct my_thread
{
static boost::thread::attributes getThreadAttr()
{
boost::thread::attributes attrs;
attrs.set_stack_size( 256 * 1024 );
return attrs;
}
my_thread( Runnable func )
: thread_( getThreadAttr(), func )
{}
boost::thread thread_;
};
But that fails:
g++ -std=c++0x -o thread-attr thread-attr.cpp \
-lboost_thread-mt -lboost_system -pthread
...
/usr/include/boost/thread/detail/thread.hpp:191:9: note: \
template argument deduction/substitution failed:
thread-attr.cpp:48:42: note: cannot convert ¡my_thread::getThreadAttr()()¢ (type \
¡boost::thread::attributes {aka boost::thread_attributes}¢) to type
¡boost::thread::attributes& {aka boost::thread_attributes&}¢
Which Boost version are you using. the thread constructor is
expecting a constant reference.
thread(attributes const& attrs, BOOST_THREAD_RV_REF(F)
f):
I would analyze later on why your example doesn't works.
Replacing 'getThreadAttr' with a method that returns a non-const
reference to internal static variables allows the program to compile
and run successfully:
static boost::thread::attributes & getThreadAttr()
{
static boost::thread::attributes attrs;
static bool init = false;
if ( ! init )
{
attrs.set_stack_size( 256 * 1024 );
init = true;
}
return attrs;
}
The full program, with Linux compile lines, can be found at the bottom
of this message and also at:
http://foiani.home.dyndns.org/~tony/boost/thread-attr.cpp
I did find a closely-related question on StackOverflow:
http://stackoverflow.com/questions/13868619
Where Vicente replied (http://stackoverflow.com/a/13894968/784478):
The needed overload
template <class F, class Arg, class ...Args>
thread(attributes const& attrs, F&& f, Arg&& arg, Args&&... args)
is defined only if the compiler supports variadic templates and
rvalue references. This could explain your problem.
I guess the documentation could be improved to signal this
clearly. Please could you create a Trac ticket to follow this
issue?
The issue you mention needed variadic templates
boost::thread causeTrouble(attrs,foo,42);
However, the compiler I'm using (g++ 4.7.2) has supported both of
these features for years. According to this page:
http://gcc.gnu.org/projects/cxx0x.html
g++ has supported both of these features since 4.3.
This is a little bit more tricky
// VARIADIC_THREAD
#if ! defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD \
&& ! defined BOOST_THREAD_DONT_PROVIDE_VARIADIC_THREAD
#if ! defined(BOOST_NO_SFINAE_EXPR) && \
! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
! defined(BOOST_NO_CXX11_DECLTYPE) && \
! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
! defined(BOOST_NO_CXX11_AUTO) && \
! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
! defined(BOOST_NO_CXX11_HDR_TUPLE)
#define BOOST_THREAD_PROVIDES_VARIADIC_THREAD
#endif
#endif
Josef_K (on freenode IRC #boost channel) was kind enough to try the
sample code in their own environment, and they encountered the same
errors on both g++ 4.8.1 and clang 3.4.
The most likely explanation is that I'm doing something stupid. If
anyone has the time to hit me with the clue-by-four, I would
appreciate it.
There is the possibility that Boost.Thread v4 fixes this (I'm on
1_51_0, which is Boost.Thread v3.0.1). I'd rather not try to
transition libraries at this point, but if it has been fixed,
confirmation would be welcome.
For now, I'll most likely implement the "return reference to internal
static" method in my project. It's a bit racy, but since I do all my
thread creation through this one routine, I should be able to manage
it.
An alternative could be
my_thread( Runnable func )
: thread_( )
{
boost::thread::attributes attrs;
attrs.set_stack_size( 256 * 1024 );
thread_ = thread(attrs, func);
}
boost::thread thread_;
};
Anyway. I'm left feeling that there is a gap somewhere; whether it's
in my understanding, in the older version of Boost.Threads, in
compiler support / quirks, or elsewhere, I don't know.
I agree that the documentation can be improved to signal all the
non-supported features due to lack of compiler features (or that I
have not yet found an C++98 portable version :()
Regardless, thanks for the excellent library, and happy hacking!
You are welcome.
Vicente