c++11 thread on g++ and linux
Check your g++
$ g++ -v Using built-in specs. Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)
This line means...
Thread model: posix
Your g++ ( std::thread in libstdc++.so ) was configured to using posix thread.
So you have to add "-pthread" option to COMPILER and LINKER when you are using std::thread.
In addition, you also have to add "-std=gnu++0x" or "-std=gnu++11" option to COMPILER to enable c++11 features.
Example
- compile
g++ thread.cc -c -o thread.o -std=gnu++0x -pthread
- link
g++ thread.o -o thread -pthread
Let's std::thread
Simple case
#include <iostream> #include <thread> void thread_handlar(){ sleep(2); std::cout << __PRETTY_FUNCTION__ << std::endl; } int main ( int argc , char * argv[] ){ std::thread t(thread_handler); sleep(1); std::cout << __PRETTY_FUNCTION__ << std::endl; t.join(); std::cout << "END" << std::endl; return 0; }
- result
int main(int, char**) void thread_handlar() END
std::thread instance is movable !!
- simple move
int main ( int argc , char * argv[] ){ std::thread t; t = std::move(std::thread(thread_handlar)); sleep(1); std::cout << __PRETTY_FUNCTION__ << std::endl; t.join(); std::cout << "END" << std::endl; return 0; }
- swap
int main ( int argc , char * argv[] ){ std::thread t1( thread_handlar ); std::thread t2( thread_handlar ); std::cout << t1.get_id() << " " << t2.get_id() << std::endl; std::swap(t1,t2); std::cout << t1.get_id() << " " << t2.get_id() << std::endl; t2.join(); t1.join(); return 0; }
- result
140431314597632 140431304107776 140431304107776 140431314597632
So you can store std::thread object to STL containers !!
#include <iostream> #include <vector> #include <thread> void thread_handlar(){ sleep(2); std::cout << __PRETTY_FUNCTION__ << std::endl; } typedef std::vector<std::thread> threads_t; int main ( int argc , char * argv[] ){ threads_t threads; for ( int i = 0 ; i < 5 ; i++ ) { threads.push_back(std::thread(thread_handlar)); } sleep(1); for ( threads_t::iterator it(threads.begin()),itend(threads.end()); it != itend; it++ ) { it->join(); } std::cout << __PRETTY_FUNCTION__ << std::endl; std::cout << "END" << std::endl; return 0; }
- result
void thread_handlar() void thread_handlar() void thread_handlar() void thread_handlar() void thread_handlar() int main(int, char**) END
std::thread supports implicit type conversion of arguments.
- FROM const char * TO const string &
#include <iostream> #include <vector> #include <thread> void thread_handlar(const std::string &msg){ sleep(2); std::cout << __PRETTY_FUNCTION__ << " : " << msg << std::endl; } int main ( int argc , char * argv[] ){ std::thread t(std::bind(thread_handlar,"kick by main() !!")); std::cout << __PRETTY_FUNCTION__ << std::endl; t.join(); std::cout << "END" << std::endl; return 0; }
std::thread supports class instance.
functor
#include <iostream> #include <thread> class MyThread { public: const std::string msg; MyThread(const std::string &msg = "default"):msg(msg){} void operator()() { sleep(2); std::cout << __PRETTY_FUNCTION__ << " : " << msg << std::endl; } }; int main ( int argc , char * argv[] ){ MyThread mythread("foo"); std::thread t(mythread); std::cout << __PRETTY_FUNCTION__ << std::endl; t.join(); std::cout << "END" << std::endl; return 0; }
- Offcause you can do this
std::thread t(MyThread("foo"));
- result
int main(int, char**) void MyThread::operator()() : foo END
other member function
#include <iostream> #include <thread> class MyThread { public: const std::string msg; MyThread(const std::string &msg = "default"):msg(msg){} void thread_handlar() { sleep(2); std::cout << __PRETTY_FUNCTION__ << " : " << msg << std::endl; } }; int main ( int argc , char * argv[] ){ MyThread mythread("foo"); std::thread t( &MyThread::thread_handlar,&mythread); std::cout << __PRETTY_FUNCTION__ << std::endl; t.join(); std::cout << "END" << std::endl; return 0; }
std::call_once is available instead of pthread_once
- we can control more precisely it by once_flag
#include <iostream> #include <mutex> #include <thread> static std::once_flag flg; void once(){ std::cout << __PRETTY_FUNCTION__ << std::endl; } void thread_handlar() { std::cout << __PRETTY_FUNCTION__ << std::endl; for ( int i = 0 ; i < 10 ; i++ ) { std::call_once(flg,once); } } int main ( int argc , char * argv[] ){ for ( int i = 0 ; i < 10 ; i++ ) { std::thread t( thread_handlar ); t.detach(); } sleep(1); return 0; }
- result
void thread_handlar() void once() void thread_handlar() void thread_handlar() void thread_handlar() void thread_handlar() void thread_handlar() void thread_handlar() void thread_handlar() void thread_handlar() void thread_handlar()
closure ( since g++ 4.5 )
simple closure
int main ( int argc , char * argv[] ){ auto lambda = [](){std::cout << __PRETTY_FUNCTION__ << std::endl; }; lambda(); }
- result
main(int, char**)::<lambda()>
- Offcause, you can call directly
int main ( int argc , char * argv[] ){ [](){std::cout << __PRETTY_FUNCTION__ << std::endl; }(); }
- example
static std::once_flag flg; int main ( int argc , char * argv[] ){ void thread_handlar() { std::call_once(flg,[](){std::cout << __PRETTY_FUNCTION__ << std::endl;} ); }
with argument
#include <iostream> struct My { const std::string n; My(const std::string &n) : n(n){} void name() const { std::cout << n << std::endl; } }; int main ( int argc , char * argv[] ){ My my("FOO"); [my](){ my.name(); }(); }
- result
FOO
with this
struct My { const std::string n; My(const std::string &n) : n(n){} void name() const { std::cout << n << std::endl; } void go() { [this](){ name();}() ; } };