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_{};
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
335 NEFORCE_NODISCARD id get_id() const noexcept { return id_; }
336
341 NEFORCE_NODISCARD native_handle_type native_handle() const noexcept { return handle_; }
342
349 NEFORCE_NODISCARD bool joinable() const noexcept { return state_ == CREATED; }
350
357 void join();
358
365 void detach();
366
373 bool set_name(const char* name);
374
381 bool name(char* buffer, size_t size) const;
382
387 void swap(thread& other) noexcept;
388
395 static bool set_name(native_handle_type handle, const char* name);
396
404 static bool name(native_handle_type handle, char* buffer, size_t size);
405};
406 // Thread
408 // AsyncComponents
410
411NEFORCE_BEGIN_THIS_THREAD__
412
418
424
429NEFORCE_ALWAYS_INLINE_INLINE thread::id id() noexcept {
430#ifdef NEFORCE_PLATFORM_WINDOWS
431 return thread::id(::GetCurrentThreadId());
432#else
433 return thread::id(::pthread_self());
434#endif
435}
436
441NEFORCE_ALWAYS_INLINE_INLINE thread::native_handle_type handle() noexcept {
442#ifdef NEFORCE_PLATFORM_WINDOWS
443 return ::GetCurrentThread();
444#else
445 return ::pthread_self();
446#endif
447}
448
455NEFORCE_ALWAYS_INLINE_INLINE bool name(char* buffer, size_t size) {
456 return thread::name(this_thread::handle(), buffer, size);
457}
458
464NEFORCE_ALWAYS_INLINE_INLINE bool set_name(const char* name) { return thread::set_name(this_thread::handle(), name); }
465 // Thread
467 // AsyncComponents
469
470NEFORCE_END_THIS_THREAD__
471
472NEFORCE_END_NAMESPACE__
473#endif // NEFORCE_CORE_ASYNC_THREAD_HPP__
元组应用函数
线程类
~thread()
析构函数
bool set_name(const char *name)
设置线程名称
thread() noexcept=default
默认构造函数
NEFORCE_NODISCARD id get_id() const noexcept
获取线程标识符
static bool name(native_handle_type handle, char *buffer, size_t size)
获取指定线程的名称
void swap(thread &other) noexcept
交换两个线程对象
thread(thread &&other) noexcept
移动构造函数
::pthread_t native_handle_type
系统线程句柄类型
NEFORCE_NODISCARD native_handle_type native_handle() const noexcept
获取原生句柄
thread & operator=(thread &&other) noexcept
移动赋值运算符
NEFORCE_NODISCARD bool joinable() const noexcept
检查线程是否可被等待
bool name(char *buffer, size_t size) const
获取线程名称
void join()
等待线程结束
static bool set_name(native_handle_type handle, const char *name)
设置指定线程的名称
void detach()
分离线程
异常处理框架
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
unsigned char byte_t
字节类型,定义为无符号字符
NEFORCE_CONSTEXPR14 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)))
移动范围元素
NEFORCE_ALWAYS_INLINE_INLINE bool set_name(const char *name)
设置当前线程名称
NEFORCE_ALWAYS_INLINE_INLINE thread::id id() noexcept
获取当前线程标识符
NEFORCE_ALWAYS_INLINE_INLINE bool name(char *buffer, size_t size)
获取当前线程名称
NEFORCE_ALWAYS_INLINE_INLINE thread::native_handle_type handle() noexcept
获取当前线程句柄
NEFORCE_NODISCARD 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的便捷别名
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) size(const Container &cont) noexcept(noexcept(cont.size()))
获取容器的大小
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
NEFORCE_INLINE17 constexpr bool is_same_v
is_same的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
NEFORCE_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr
exception(const char *info=static_type, const char *type=static_type, const int code=0)
构造函数
NEFORCE_NODISCARD int code() const noexcept
获取异常码
NEFORCE_NODISCARD const char * type() 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)
移除钩子回调
线程唯一标识符类
NEFORCE_NODISCARD bool operator==(const id &rhs) const noexcept
等于比较运算符
NEFORCE_NODISCARD bool operator!=(const id &rhs) const noexcept
不等于比较运算符
id() noexcept=default
默认构造函数
NEFORCE_NODISCARD size_t to_hash() const noexcept
计算哈希值
NEFORCE_NODISCARD native_id_type native_handle() const noexcept
获取原生线程ID
当前线程操作
独占智能指针