NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
thread.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_ASYNC_THREAD_HPP__
2#define NEFORCE_CORE_ASYNC_THREAD_HPP__
3
11
16#ifdef NEFORCE_PLATFORM_LINUX
17# include <pthread.h>
18#endif
19NEFORCE_BEGIN_NAMESPACE__
20
26
31struct thread_exception final : system_exception {
32 explicit thread_exception(const char* info = "Thread Operation Failed.", const char* type = static_type,
33 const int code = 0) noexcept :
34 system_exception(info, type, code) {}
35
36 explicit thread_exception(const exception& e) :
37 system_exception(e) {}
38
39 ~thread_exception() override = default;
40
41 static constexpr auto static_type = "thread_exception";
42};
43 // Exceptions
45
51
57
65class NEFORCE_API thread {
66public:
73 struct id : ihashable<id> {
74 private:
78 using native_id_type =
79#ifdef NEFORCE_PLATFORM_WINDOWS
80 ::DWORD;
81#else
82 ::pthread_t;
83#endif
84
85 native_id_type id_{};
86
87 friend class thread;
88
89 public:
93 id() noexcept = default;
94
99 explicit id(const native_id_type id) noexcept :
100 id_(id) {}
101
106 NEFORCE_NODISCARD native_id_type native_handle() const noexcept { return id_; }
107
112 NEFORCE_NODISCARD size_t to_hash() const noexcept {
113 return _NEFORCE FNV_hash(reinterpret_cast<const byte_t*>(&id_), sizeof(id));
114 }
115
121 NEFORCE_NODISCARD bool operator==(const id& rhs) const noexcept {
122#ifdef NEFORCE_PLATFORM_WINDOWS
123 return id_ == rhs.id_;
124#else
125 return ::pthread_equal(id_, rhs.id_) != 0;
126#endif
127 }
128
134 NEFORCE_NODISCARD bool operator!=(const id& rhs) const noexcept { return !(*this == rhs); }
135 };
136
143 struct NEFORCE_API hook {
148 enum class point {
149 before_create,
150 after_create,
151 thread_start,
152 thread_end,
153 before_destroy
154 };
155
156 using callback_t = void (*)(point point, id thread_id);
157
163
169
175 static void invoke(point point, id thread_id);
176 };
177
178private:
183 enum state {
184 NOT_A_THREAD,
185 CREATED,
186 JOINED,
187 DETACHED
188 };
189
196 struct data_base {
197 virtual ~data_base() = default;
198 virtual void run() = 0;
199 };
200
206 template <typename Callable>
207 struct thread_data final : data_base {
208 Callable func_;
209
210 template <typename F>
211 explicit thread_data(F&& f) :
212 func_(_NEFORCE forward<F>(f)) {}
213
214 void run() override { func_(); }
215 };
216
223 struct thread_startup_args {
224 unique_ptr<data_base> data;
225 id thread_id;
226 };
227
234 struct NEFORCE_API thread_monitor {
235 private:
236 id thread_id_;
237
238 public:
243 explicit thread_monitor(id thread_id);
244
248 ~thread_monitor() noexcept;
249 };
250
251public:
256#ifdef NEFORCE_PLATFORM_WINDOWS
257 ::HANDLE;
258#else
259 ::pthread_t;
260#endif
261
262private:
263 native_handle_type handle_{};
264 id id_{0};
265 state state_ = NOT_A_THREAD;
266
267#ifdef NEFORCE_PLATFORM_WINDOWS
268 static unsigned int __stdcall thread_entry(void* arg);
269#else
270 static void* thread_entry(void* arg);
271#endif
272
273 void start_thread_impl(thread_startup_args* args);
274
275 template <typename F>
276 void start_thread(F&& f) {
277 auto data = _NEFORCE make_unique<thread_data<decay_t<F>>>(_NEFORCE forward<F>(f));
278 this->start_thread_impl(new thread_startup_args{_NEFORCE move(data), id_});
279 }
280
281public:
287 thread() noexcept = default;
288
301 template <typename F, typename... Args, typename = enable_if_t<!is_same_v<decay_t<F>, thread>>>
302 explicit thread(F&& f, Args&&... args) {
303 auto func = [func = _NEFORCE move(f), args = _NEFORCE make_tuple(_NEFORCE forward<Args>(args)...)]() mutable {
304 return _NEFORCE apply(_NEFORCE move(func), _NEFORCE move(args));
305 };
306 thread::start_thread(_NEFORCE move(func));
307 }
308
309 thread(const thread&) = delete;
310 thread& operator=(const thread&) = delete;
311
316 thread(thread&& other) noexcept;
317
323 thread& operator=(thread&& other) noexcept;
324
330
339 template <typename F, typename... Args>
340 void start(F&& f, Args&&... args) {
341 if (state_ != NOT_A_THREAD) {
342 NEFORCE_THROW_EXCEPTION(thread_exception("Thread already started or has been joined/detached."));
343 }
344 auto func = [func = _NEFORCE forward<F>(f),
345 args = _NEFORCE make_tuple(_NEFORCE forward<Args>(args)...)]() mutable {
346 return _NEFORCE apply(_NEFORCE move(func), _NEFORCE move(args));
347 };
348 this->start_thread(_NEFORCE move(func));
349 }
350
355 NEFORCE_NODISCARD id get_id() const noexcept { return id_; }
356
361 NEFORCE_NODISCARD native_handle_type native_handle() const noexcept { return handle_; }
362
369 NEFORCE_NODISCARD bool joinable() const noexcept { return state_ == CREATED; }
370
377 void join();
378
385 void detach();
386
393 bool set_name(const char* name);
394
401 bool name(char* buffer, size_t size) const;
402
407 void swap(thread& other) noexcept;
408
415 static bool set_name(native_handle_type handle, const char* name);
416
424 static bool name(native_handle_type handle, char* buffer, size_t size);
425};
426 // Thread
428 // AsyncComponents
430
431NEFORCE_BEGIN_THIS_THREAD__
432
438
444
449NEFORCE_ALWAYS_INLINE_INLINE thread::id id() noexcept {
450#ifdef NEFORCE_PLATFORM_WINDOWS
451 return thread::id(::GetCurrentThreadId());
452#else
453 return thread::id(::pthread_self());
454#endif
455}
456
461NEFORCE_ALWAYS_INLINE_INLINE thread::native_handle_type handle() noexcept {
462#ifdef NEFORCE_PLATFORM_WINDOWS
463 return ::GetCurrentThread();
464#else
465 return ::pthread_self();
466#endif
467}
468
475NEFORCE_ALWAYS_INLINE_INLINE bool name(char* buffer, size_t size) {
476 return thread::name(this_thread::handle(), buffer, size);
477}
478
484NEFORCE_ALWAYS_INLINE_INLINE bool set_name(const char* name) { return thread::set_name(this_thread::handle(), name); }
485 // Thread
487 // AsyncComponents
489
490NEFORCE_END_THIS_THREAD__
491
492NEFORCE_END_NAMESPACE__
493#endif // NEFORCE_CORE_ASYNC_THREAD_HPP__
元组应用函数
线程类
~thread()
析构函数
bool set_name(const char *name)
设置线程名称
thread() noexcept=default
默认构造函数
native_handle_type native_handle() const noexcept
获取原生句柄
static bool name(native_handle_type handle, char *buffer, size_t size)
获取指定线程的名称
void swap(thread &other) noexcept
交换两个线程对象
::HANDLE native_handle_type
系统线程句柄类型
thread(thread &&other) noexcept
移动构造函数
thread & operator=(thread &&other) noexcept
移动赋值运算符
bool joinable() const noexcept
检查线程是否可被等待
bool name(char *buffer, size_t size) const
获取线程名称
void join()
等待线程结束
void start(F &&f, Args &&... args)
延迟启动线程
static bool set_name(native_handle_type handle, const char *name)
设置指定线程的名称
id get_id() const noexcept
获取线程标识符
void detach()
分离线程
异常处理框架
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
unsigned char byte_t
字节类型,定义为无符号字符
constexpr size_t FNV_hash(const byte_t *first, const size_t count) noexcept
FNV-1a哈希算法
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
bool name(char *buffer, size_t size)
获取当前线程名称
bool set_name(const char *name)
设置当前线程名称
thread::native_handle_type handle() noexcept
获取当前线程句柄
thread::id id() noexcept
获取当前线程标识符
constexpr tuple< unwrap_ref_decay_t< Types >... > make_tuple(Types &&... args)
从参数创建元组
constexpr decltype(auto) apply(Func &&f, Tuple &&t) noexcept(inner::__apply_unpack_tuple< _NEFORCE is_nothrow_invocable, Func, Tuple >::value)
将元组元素解包作为参数调用函数
typename decay< T >::type decay_t
decay的便捷别名
constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
constexpr bool is_same_v
is_same的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
exception(const char *info=static_type, const char *type=static_type, const int code=0)
构造函数
const char * type() const noexcept
获取异常类型
int code() const noexcept
获取异常码
可哈希对象接口模板
线程生命周期钩子
static void add_hook(callback_t hook)
添加钩子回调
static void invoke(point point, id thread_id)
调用钩子回调
void(*)(point point, id thread_id) callback_t
钩子回调函数类型
point
钩子触发点枚举
static void remove_hook(callback_t hook)
移除钩子回调
线程唯一标识符类
bool operator==(const id &rhs) const noexcept
等于比较运算符
bool operator!=(const id &rhs) const noexcept
不等于比较运算符
id() noexcept=default
默认构造函数
size_t to_hash() const noexcept
计算哈希值
native_id_type native_handle() const noexcept
获取原生线程ID
线程操作异常
当前线程操作
独占智能指针