thread
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _GLIBCXX_THREAD
00030 #define _GLIBCXX_THREAD 1
00031
00032 #pragma GCC system_header
00033
00034 #ifndef __GXX_EXPERIMENTAL_CXX0X__
00035 # include <c++0x_warning.h>
00036 #else
00037
00038 #include <chrono>
00039 #include <functional>
00040 #include <memory>
00041 #include <mutex>
00042 #include <condition_variable>
00043 #include <cstddef>
00044 #include <bits/functexcept.h>
00045 #include <bits/gthr.h>
00046
00047 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
00048
00049 namespace std
00050 {
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 class thread
00061 {
00062 public:
00063 typedef __gthread_t native_handle_type;
00064 struct _Impl_base;
00065 typedef shared_ptr<_Impl_base> __shared_base_type;
00066
00067
00068 class id
00069 {
00070 native_handle_type _M_thread;
00071
00072 public:
00073 id() : _M_thread() { }
00074
00075 explicit
00076 id(native_handle_type __id) : _M_thread(__id) { }
00077
00078 private:
00079 friend class thread;
00080
00081 friend bool
00082 operator==(thread::id __x, thread::id __y)
00083 { return __gthread_equal(__x._M_thread, __y._M_thread); }
00084
00085 friend bool
00086 operator<(thread::id __x, thread::id __y)
00087 { return __x._M_thread < __y._M_thread; }
00088
00089 template<class _CharT, class _Traits>
00090 friend basic_ostream<_CharT, _Traits>&
00091 operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id);
00092 };
00093
00094
00095
00096 struct _Impl_base
00097 {
00098 __shared_base_type _M_this_ptr;
00099
00100 virtual ~_Impl_base() = default;
00101
00102 virtual void _M_run() = 0;
00103 };
00104
00105 template<typename _Callable>
00106 struct _Impl : public _Impl_base
00107 {
00108 _Callable _M_func;
00109
00110 _Impl(_Callable&& __f) : _M_func(std::forward<_Callable>(__f))
00111 { }
00112
00113 void
00114 _M_run() { _M_func(); }
00115 };
00116
00117 private:
00118 id _M_id;
00119
00120 public:
00121 thread() = default;
00122 thread(const thread&) = delete;
00123
00124 thread(thread&& __t)
00125 { swap(__t); }
00126
00127 template<typename _Callable>
00128 explicit thread(_Callable __f)
00129 {
00130 _M_start_thread(_M_make_routine<_Callable>
00131 (std::forward<_Callable>(__f)));
00132 }
00133
00134 template<typename _Callable, typename... _Args>
00135 thread(_Callable&& __f, _Args&&... __args)
00136 { _M_start_thread(_M_make_routine(std::bind(__f, __args...))); }
00137
00138 ~thread()
00139 {
00140 if (joinable())
00141 std::terminate();
00142 }
00143
00144 thread& operator=(const thread&) = delete;
00145
00146 thread& operator=(thread&& __t)
00147 {
00148 if (joinable())
00149 std::terminate();
00150 swap(__t);
00151 return *this;
00152 }
00153
00154 void
00155 swap(thread& __t)
00156 { std::swap(_M_id, __t._M_id); }
00157
00158 bool
00159 joinable() const
00160 { return !(_M_id == id()); }
00161
00162 void
00163 join();
00164
00165 void
00166 detach();
00167
00168 thread::id
00169 get_id() const
00170 { return _M_id; }
00171
00172
00173
00174 native_handle_type
00175 native_handle()
00176 { return _M_id._M_thread; }
00177
00178
00179 static unsigned int
00180 hardware_concurrency()
00181 { return 0; }
00182
00183 private:
00184 void
00185 _M_start_thread(__shared_base_type);
00186
00187 template<typename _Callable>
00188 shared_ptr<_Impl<_Callable>>
00189 _M_make_routine(_Callable&& __f)
00190 {
00191
00192 return make_shared<_Impl<_Callable>>(std::forward<_Callable>(__f));
00193 }
00194 };
00195
00196 inline void
00197 swap(thread& __x, thread& __y)
00198 { __x.swap(__y); }
00199
00200 inline bool
00201 operator!=(thread::id __x, thread::id __y)
00202 { return !(__x == __y); }
00203
00204 inline bool
00205 operator<=(thread::id __x, thread::id __y)
00206 { return !(__y < __x); }
00207
00208 inline bool
00209 operator>(thread::id __x, thread::id __y)
00210 { return __y < __x; }
00211
00212 inline bool
00213 operator>=(thread::id __x, thread::id __y)
00214 { return !(__x < __y); }
00215
00216 template<class _CharT, class _Traits>
00217 inline basic_ostream<_CharT, _Traits>&
00218 operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id)
00219 {
00220 if (__id == thread::id())
00221 return __out << "thread::id of a non-executing thread";
00222 else
00223 return __out << __id._M_thread;
00224 }
00225
00226
00227
00228
00229
00230 namespace this_thread
00231 {
00232
00233 inline thread::id
00234 get_id() { return thread::id(__gthread_self()); }
00235
00236 #ifdef _GLIBCXX_USE_SCHED_YIELD
00237
00238 inline void
00239 yield()
00240 { __gthread_yield(); }
00241 #endif
00242
00243 #ifdef _GLIBCXX_USE_NANOSLEEP
00244
00245 template<typename _Clock, typename _Duration>
00246 inline void
00247 sleep_until(const chrono::time_point<_Clock, _Duration>& __atime)
00248 { sleep_for(__atime - _Clock::now()); }
00249
00250
00251 template<typename _Rep, typename _Period>
00252 inline void
00253 sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
00254 {
00255 chrono::seconds __s =
00256 chrono::duration_cast<chrono::seconds>(__rtime);
00257
00258 chrono::nanoseconds __ns =
00259 chrono::duration_cast<chrono::nanoseconds>(__rtime - __s);
00260
00261 __gthread_time_t __ts =
00262 {
00263 static_cast<std::time_t>(__s.count()),
00264 static_cast<long>(__ns.count())
00265 };
00266
00267 ::nanosleep(&__ts, 0);
00268 }
00269 #endif
00270 }
00271
00272
00273 }
00274
00275 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
00276
00277 #endif // __GXX_EXPERIMENTAL_CXX0X__
00278
00279 #endif // _GLIBCXX_THREAD