libstdc++
std_thread.h
Go to the documentation of this file.
1 // std::thread declarations -*- C++ -*-
2 
3 // Copyright (C) 2008-2023 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file bits/std_thread.h
26  * This is an internal header file, included by other library headers.
27  * Do not attempt to use it directly. @headername{thread}
28  */
29 
30 #ifndef _GLIBCXX_THREAD_H
31 #define _GLIBCXX_THREAD_H 1
32 
33 #pragma GCC system_header
34 
35 #if __cplusplus >= 201103L
36 #include <bits/c++config.h>
37 
38 #include <iosfwd> // std::basic_ostream
39 #include <tuple> // std::tuple
40 #include <bits/functional_hash.h> // std::hash
41 #include <bits/invoke.h> // std::__invoke
42 #include <bits/refwrap.h> // not required, but helpful to users
43 #include <bits/unique_ptr.h> // std::unique_ptr
44 
45 #ifdef _GLIBCXX_HAS_GTHREADS
46 # include <bits/gthr.h>
47 #else
48 # include <errno.h>
49 # include <bits/functexcept.h>
50 #endif
51 
52 namespace std _GLIBCXX_VISIBILITY(default)
53 {
54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 
56  /** @addtogroup threads
57  * @{
58  */
59 
60  /** A std::thread represents a new thread of execution.
61  *
62  * The default constructor creates an object that does not own a thread.
63  * The `thread(F&&, Args&&...)` constructor invokes a callable in a new
64  * thread, and owns that new thread. A `std::thread` that owns a thread
65  * is *joinable*. Joining a thread waits for it to finish executing,
66  * which happens when the callable running in that thread returns.
67  *
68  * A `std::thread` cannot be copied, but can be moved. Moving a joinable
69  * object transfers ownership of its thread to another object.
70  *
71  * A joinable `std::thread` must be explicitly joined (or detached) before
72  * it is destroyed or assigned to. Attempting to destroy a joinable thread
73  * will terminate the whole process.
74  *
75  * @headerfile thread
76  * @since C++11
77  */
78  class thread
79  {
80  public:
81 #ifdef _GLIBCXX_HAS_GTHREADS
82  using native_handle_type = __gthread_t;
83 #else
84  using native_handle_type = int;
85 #endif
86 
87  /** A std::thread::id is a unique identifier for a thread.
88  *
89  * @headerfile thread
90  * @since C++11
91  */
92  class id
93  {
94  native_handle_type _M_thread;
95 
96  public:
97  id() noexcept : _M_thread() { }
98 
99  explicit
100  id(native_handle_type __id) : _M_thread(__id) { }
101 
102  private:
103  friend class thread;
104  friend struct hash<id>;
105 
106  friend bool
107  operator==(id __x, id __y) noexcept;
108 
109 #if __cpp_lib_three_way_comparison
110  friend strong_ordering
111  operator<=>(id __x, id __y) noexcept;
112 #else
113  friend bool
114  operator<(id __x, id __y) noexcept;
115 #endif
116 
117  template<class _CharT, class _Traits>
120  };
121 
122  private:
123  id _M_id;
124 
125  // _GLIBCXX_RESOLVE_LIB_DEFECTS
126  // 2097. packaged_task constructors should be constrained
127  // 3039. Unnecessary decay in thread and packaged_task
128  template<typename _Tp>
129  using __not_same = __not_<is_same<__remove_cvref_t<_Tp>, thread>>;
130 
131  public:
132  thread() noexcept = default;
133 
134 #ifdef _GLIBCXX_HAS_GTHREADS
135  private:
136  // This adds to user code that creates std:thread objects (because
137  // it is called by the template ctor below) strong references to
138  // pthread_create and pthread_join, which ensures they are both
139  // linked in even during static linking. We can't depend on
140  // gthread calls to bring them in, because those may use weak
141  // references.
142  static void
143  _M_thread_deps_never_run() {
144 #ifdef GTHR_ACTIVE_PROXY
145  reinterpret_cast<void (*)(void)>(&pthread_create)();
146  reinterpret_cast<void (*)(void)>(&pthread_join)();
147 #endif
148  }
149 
150  public:
151  template<typename _Callable, typename... _Args,
152  typename = _Require<__not_same<_Callable>>>
153  explicit
154  thread(_Callable&& __f, _Args&&... __args)
155  {
156  static_assert( __is_invocable<typename decay<_Callable>::type,
157  typename decay<_Args>::type...>::value,
158  "std::thread arguments must be invocable after conversion to rvalues"
159  );
160 
161  using _Wrapper = _Call_wrapper<_Callable, _Args...>;
162  // Create a call wrapper with DECAY_COPY(__f) as its target object
163  // and DECAY_COPY(__args)... as its bound argument entities.
164  _M_start_thread(_State_ptr(new _State_impl<_Wrapper>(
165  std::forward<_Callable>(__f), std::forward<_Args>(__args)...)),
166  _M_thread_deps_never_run);
167  }
168 #endif // _GLIBCXX_HAS_GTHREADS
169 
170  ~thread()
171  {
172  if (joinable())
173  std::__terminate();
174  }
175 
176  thread(const thread&) = delete;
177 
178  thread(thread&& __t) noexcept
179  { swap(__t); }
180 
181  thread& operator=(const thread&) = delete;
182 
183  thread& operator=(thread&& __t) noexcept
184  {
185  if (joinable())
186  std::__terminate();
187  swap(__t);
188  return *this;
189  }
190 
191  void
192  swap(thread& __t) noexcept
193  { std::swap(_M_id, __t._M_id); }
194 
195  bool
196  joinable() const noexcept
197  { return !(_M_id == id()); }
198 
199  void
200  join();
201 
202  void
203  detach();
204 
205  id
206  get_id() const noexcept
207  { return _M_id; }
208 
209  /** @pre thread is joinable
210  */
211  native_handle_type
213  { return _M_id._M_thread; }
214 
215  // Returns a value that hints at the number of hardware thread contexts.
216  static unsigned int
217  hardware_concurrency() noexcept;
218 
219 #ifdef _GLIBCXX_HAS_GTHREADS
220 #ifndef _GLIBCXX_THREAD_IMPL
221  private:
222 #endif
223  // Abstract base class for types that wrap arbitrary functors to be
224  // invoked in the new thread of execution.
225  struct _State
226  {
227  virtual ~_State();
228  virtual void _M_run() = 0;
229  };
230  using _State_ptr = unique_ptr<_State>;
231 
232  private:
233  template<typename _Callable>
234  struct _State_impl : public _State
235  {
236  _Callable _M_func;
237 
238  template<typename... _Args>
239  _State_impl(_Args&&... __args)
240  : _M_func(std::forward<_Args>(__args)...)
241  { }
242 
243  void
244  _M_run() { _M_func(); }
245  };
246 
247  void
248  _M_start_thread(_State_ptr, void (*)());
249 
250 #if _GLIBCXX_THREAD_ABI_COMPAT
251  public:
252  struct _Impl_base;
253  typedef shared_ptr<_Impl_base> __shared_base_type;
254  struct _Impl_base
255  {
256  __shared_base_type _M_this_ptr;
257  virtual ~_Impl_base() = default;
258  virtual void _M_run() = 0;
259  };
260 
261  private:
262  void
263  _M_start_thread(__shared_base_type, void (*)());
264 
265  void
266  _M_start_thread(__shared_base_type);
267 #endif
268 
269  private:
270  // A call wrapper that does INVOKE(forwarded tuple elements...)
271  template<typename _Tuple>
272  struct _Invoker
273  {
274  template<typename... _Args>
275  explicit
276  _Invoker(_Args&&... __args)
277  : _M_t(std::forward<_Args>(__args)...)
278  { }
279 
280  _Tuple _M_t;
281 
282  template<typename>
283  struct __result;
284  template<typename _Fn, typename... _Args>
285  struct __result<tuple<_Fn, _Args...>>
286  : __invoke_result<_Fn, _Args...>
287  { };
288 
289  template<size_t... _Ind>
290  typename __result<_Tuple>::type
291  _M_invoke(_Index_tuple<_Ind...>)
292  { return std::__invoke(std::get<_Ind>(std::move(_M_t))...); }
293 
294  typename __result<_Tuple>::type
295  operator()()
296  {
297  using _Indices
298  = typename _Build_index_tuple<tuple_size<_Tuple>::value>::__type;
299  return _M_invoke(_Indices());
300  }
301  };
302 
303  public:
304  /// @cond undocumented
305  template<typename... _Tp>
306  using _Call_wrapper = _Invoker<tuple<typename decay<_Tp>::type...>>;
307  /// @endcond
308 #endif // _GLIBCXX_HAS_GTHREADS
309  };
310 
311 #ifndef _GLIBCXX_HAS_GTHREADS
312  inline void thread::join() { std::__throw_system_error(EINVAL); }
313  inline void thread::detach() { std::__throw_system_error(EINVAL); }
314  inline unsigned int thread::hardware_concurrency() noexcept { return 0; }
315 #endif
316 
317  /// @relates std::thread
318  inline void
319  swap(thread& __x, thread& __y) noexcept
320  { __x.swap(__y); }
321 
322  /// @relates std::thread::id
323  inline bool
324  operator==(thread::id __x, thread::id __y) noexcept
325  {
326  // pthread_equal is undefined if either thread ID is not valid, so we
327  // can't safely use __gthread_equal on default-constructed values (nor
328  // the non-zero value returned by this_thread::get_id() for
329  // single-threaded programs using GNU libc). Assume EqualityComparable.
330  return __x._M_thread == __y._M_thread;
331  }
332 
333  // N.B. other comparison operators are defined in <thread>
334 
335  // DR 889.
336  /// std::hash specialization for thread::id.
337  template<>
338  struct hash<thread::id>
339  : public __hash_base<size_t, thread::id>
340  {
341  size_t
342  operator()(const thread::id& __id) const noexcept
343  { return std::_Hash_impl::hash(__id._M_thread); }
344  };
345 
346  namespace this_thread
347  {
348  /// The unique identifier of the current thread.
349  inline thread::id
350  get_id() noexcept
351  {
352 #ifndef _GLIBCXX_HAS_GTHREADS
353  return thread::id(1);
354 #elif defined _GLIBCXX_NATIVE_THREAD_ID
355  return thread::id(_GLIBCXX_NATIVE_THREAD_ID);
356 #else
357  return thread::id(__gthread_self());
358 #endif
359  }
360 
361  /// Allow the implementation to schedule a different thread.
362  inline void
363  yield() noexcept
364  {
365 #if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
366  __gthread_yield();
367 #endif
368  }
369 
370  } // namespace this_thread
371 
372  /// @}
373 
374 _GLIBCXX_END_NAMESPACE_VERSION
375 } // namespace
376 #endif // C++11
377 
378 #endif // _GLIBCXX_THREAD_H
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
Definition: invoke.h:90
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:97
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:70
void swap(any &__x, any &__y) noexcept
Exchange the states of two any objects.
Definition: any:429
ISO C++ entities toplevel namespace is std.
std::basic_ostream< _CharT, _Traits > & operator<<(std::basic_ostream< _CharT, _Traits > &__os, const bitset< _Nb > &__x)
Global I/O operators for bitsets.
Definition: bitset:1683
void yield() noexcept
Allow the implementation to schedule a different thread.
Definition: std_thread.h:363
thread::id get_id() noexcept
The unique identifier of the current thread.
Definition: std_thread.h:350
Template class basic_ostream.
Definition: ostream:61
Primary class template hash.
native_handle_type native_handle()
Definition: std_thread.h:212