3 #ifndef INCLUDE_NN_NLIB_THREADING_THREAD_H_
4 #define INCLUDE_NN_NLIB_THREADING_THREAD_H_
7 #include "nn/nlib/Swap.h"
30 NLIB_THREAD_ATTR_KEY_DETACHSTATE,
36 NLIB_ASSERT(m_Initialized);
40 NLIB_THREAD_ATTR_KEY_DETACHSTATE,
44 return (detached != 0);
50 NLIB_THREAD_ATTR_KEY_STACKSIZE,
55 NLIB_ASSERT(m_Initialized);
59 NLIB_THREAD_ATTR_KEY_STACKSIZE,
69 NLIB_THREAD_ATTR_KEY_PRIORITY,
74 NLIB_ASSERT(m_Initialized);
78 NLIB_THREAD_ATTR_KEY_PRIORITY,
85 return m_Initialized ? &m_Attr : NULL;
88 return m_Initialized ? &m_Attr : NULL;
104 template <
class T1 = None,
class T2 = None,
class T3 = None,
class T4 = None,
class T5 = None>
108 typedef void (*Func)(ArgType& ptr);
111 : func(func_), arg1(arg1_), arg2(arg2_), arg3(arg3_), arg4(arg4_), arg5(arg5_) {}
112 static void Call(ArgType& ptr) { ptr->func(ptr); }
123 struct ThreadArg<None, None, None, None, None> {
125 typedef void ArgType;
126 typedef void (*Func)();
130 struct ThreadArg<T1, None, None, None, None> {
131 typedef ThreadArg<T1> ThisType;
133 typedef void (*Func)(ArgType& ptr);
134 NLIB_CEXPR ThreadArg() : func(NULL), arg1() {}
135 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_) : func(func_), arg1(arg1_) {}
136 static void Call(ArgType& ptr) { ptr->func(ptr); }
142 template <
class T1,
class T2>
143 struct ThreadArg<T1, T2, None, None, None> {
144 typedef ThreadArg<T1, T2> ThisType;
145 typedef UniquePtr<ThisType> ArgType;
146 typedef void (*Func)(ArgType& ptr);
147 NLIB_CEXPR ThreadArg() : func(NULL), arg1(), arg2() {}
148 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_) : func(func_), arg1(arg1_), arg2(arg2_) {}
149 static void Call(ArgType& ptr) { ptr->func(ptr); }
156 template <
class T1,
class T2,
class T3>
157 struct ThreadArg<T1, T2, T3, None, None> {
158 typedef ThreadArg<T1, T2, T3> ThisType;
159 typedef UniquePtr<ThisType> ArgType;
160 typedef void (*Func)(ArgType& ptr);
161 NLIB_CEXPR ThreadArg() : func(NULL), arg1(), arg2(), arg3() {}
162 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_, T3 arg3_)
163 : func(func_), arg1(arg1_), arg2(arg2_), arg3(arg3_) {}
164 static void Call(ArgType& ptr) { ptr->func(ptr); }
172 template <
class T1,
class T2,
class T3,
class T4>
173 struct ThreadArg<T1, T2, T3, T4, None> {
174 typedef ThreadArg<T1, T2, T3, T4> ThisType;
175 typedef UniquePtr<ThisType> ArgType;
176 typedef void (*Func)(ArgType& ptr);
177 NLIB_CEXPR ThreadArg() : func(NULL), arg1(), arg2(), arg3(), arg4() {}
178 NLIB_CEXPR ThreadArg(Func func_, T1 arg1_, T2 arg2_, T3 arg3_, T4 arg4_)
179 : func(func_), arg1(arg1_), arg2(arg2_), arg3(arg3_), arg4(arg4_) {}
180 static void Call(ArgType& ptr) { ptr->func(ptr); }
190 #pragma warning(push)
191 #pragma warning(disable : 4180)
201 typedef void (*ThreadFunc)(
void* arg);
206 NLIB_MOVE_MEMBER_HELPER_1(
Thread, m_ThreadId)
209 return this->StartRaw(func, arg, defaultSettings);
214 if (!m_ThreadId)
return ESRCH;
241 swap(m_ThreadId, rhs.m_ThreadId);
257 errno_t e = this->StartRaw(Thread::Exec, reinterpret_cast<void*>(func), settings);
262 return this->StartRaw(defaultSettings, func);
264 template <
class ThArg>
267 if (!ptr)
return EINVAL;
268 errno_t e = this->StartRaw((ThreadFunc)Thread::Exec<ThArg>,
269 reinterpret_cast<void*>(ptr.get()), settings);
270 if (e == 0) ptr.release();
273 template <
class ThArg>
276 return this->StartRaw(defaultSettings, ptr);
280 static void Exec(
void* p) {
285 static void Exec(
void* p) {
290 #define NLIB_THFUNC_USESWAP_NO(tp) \
292 !IsSame<None, typename RemoveCv<B>::type>::value && \
293 (IsSame<FalseType, typename RemoveCv<B>::type>::value || !IsSwappable<tp>::value), \
295 #define NLIB_THFUNC_USESWAP_YES(tp) \
296 typename EnableIf<!IsSame<None, typename RemoveCv<B>::type>::value && \
297 IsSame<TrueType, typename RemoveCv<B>::type>::value && \
298 IsSwappable<tp>::value, \
302 struct ArgType :
public Conditional<
303 IsArithmetic<T>::value || IsPointer<T>::value || IsMemberPointer<T>::value,
304 FalseType, TrueType> {};
306 template <
class FUNC>
308 typedef typename RemoveRef<FUNC>::type FUNC_;
310 Args0(NLIB_THFUNC_USESWAP_NO(FUNC_) func_, B)
313 Args0(NLIB_THFUNC_USESWAP_YES(FUNC_) func_, B)
316 swap(const_cast<FUNC&>(func_), func);
319 Args0(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
328 template <
class FUNC,
class T1>
329 struct Args1 :
public Args0<FUNC> {
330 typedef Args0<FUNC> BaseType;
331 typedef typename RemoveRef<T1>::type T1_;
333 Args1(
const FUNC& func_, NLIB_THFUNC_USESWAP_NO(T1) arg1_, B)
334 : BaseType(func_, typename IsSwappable<FUNC>::type()), arg1(arg1_) {}
336 Args1(
const FUNC& func_, NLIB_THFUNC_USESWAP_YES(T1) arg1_, B)
337 : BaseType(func_, typename IsSwappable<FUNC>::type()), arg1() {
339 swap(const_cast<T1&>(arg1_), arg1);
342 Args1(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
344 const T1& arg1_, B b)
345 : BaseType(func_, b), arg1(arg1_) {}
348 template <
class FUNC,
class T1,
class T2>
349 struct Args2 :
public Args1<FUNC, T1> {
350 typedef Args1<FUNC, T1> BaseType;
351 typedef typename RemoveRef<T2>::type T2_;
353 Args2(
const FUNC& func_,
const T1& arg1_, NLIB_THFUNC_USESWAP_NO(T2) arg2_, B)
354 : BaseType(func_, arg1_, typename ArgType<T1>::type()), arg2(arg2_) {}
356 Args2(
const FUNC& func_,
const T1& arg1_, NLIB_THFUNC_USESWAP_YES(T2) arg2_, B)
357 : BaseType(func_, arg1_, typename ArgType<T1>::type()), arg2() {
359 swap(const_cast<T2&>(arg2_), arg2);
362 Args2(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
364 const T1& arg1_,
const T2& arg2_, B b)
365 : BaseType(func_, arg1_, b), arg2(arg2_) {}
368 template <
class FUNC,
class T1,
class T2,
class T3>
369 struct Args3 :
public Args2<FUNC, T1, T2> {
370 typedef Args2<FUNC, T1, T2> BaseType;
371 typedef typename RemoveRef<T3>::type T3_;
373 Args3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_, NLIB_THFUNC_USESWAP_NO(T3) arg3_,
375 : BaseType(func_, arg1_, arg2_, typename ArgType<T2>::type()), arg3(arg3_) {}
377 Args3(
const FUNC& func,
const T1& arg1_,
const T2& arg2_, NLIB_THFUNC_USESWAP_YES(T3) arg3_,
379 : BaseType(func, arg1_, arg2_, typename ArgType<T2>::type()), arg3() {
381 swap(const_cast<T3&>(arg3_), arg3);
384 Args3(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
386 const T1& arg1_,
const T2& arg2_,
const T3& arg3_, B b)
387 : BaseType(func_, arg1_, arg2_, b), arg3(arg3_) {}
390 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
391 struct Args4 :
public Args3<FUNC, T1, T2, T3> {
392 typedef Args3<FUNC, T1, T2, T3> BaseType;
393 typedef typename RemoveRef<T4>::type T4_;
395 Args4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
396 NLIB_THFUNC_USESWAP_NO(T4) arg4_, B)
397 : BaseType(func_, arg1_, arg2_, arg3_, typename ArgType<T3>::type()), arg4(arg4_) {}
399 Args4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
400 NLIB_THFUNC_USESWAP_YES(T4) arg4_, B)
401 : BaseType(func_, arg1_, arg2_, arg3_, typename ArgType<T3>::type()), arg4() {
403 swap(const_cast<T4&>(arg4_), arg4);
406 Args4(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
408 const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_, B b)
409 : BaseType(func_, arg1_, arg2_, arg3_, b), arg4(arg4_) {}
412 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
413 struct Args5 :
public Args4<FUNC, T1, T2, T3, T4> {
414 typedef Args4<FUNC, T1, T2, T3, T4> BaseType;
415 typedef typename RemoveRef<T5>::type T5_;
417 Args5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
418 NLIB_THFUNC_USESWAP_NO(T5) arg5_, B)
419 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, typename ArgType<T4>::type()),
422 Args5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
423 NLIB_THFUNC_USESWAP_YES(T4) arg5_, B)
424 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, typename ArgType<T4>::type()), arg5() {
426 swap(const_cast<T5&>(arg5_), arg5);
429 Args5(
typename EnableIf<IsSame<
typename RemoveCv<B>::type, None>::value,
const FUNC&>::type
431 const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
const T4& arg4_,
const T5& arg5_,
433 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, b), arg5(arg5_) {}
436 #undef NLIB_THFUNC_USESWAP_NO
437 #undef NLIB_THFUNC_USESWAP_YES
439 template <
class FUNC>
440 struct ThreadFuncX0 :
public Args0<FUNC> {
441 typedef ThreadFuncX0<FUNC> ThisType;
442 typedef Args0<FUNC> BaseType;
444 ThreadFuncX0(
const FUNC& func_, B b)
445 : BaseType(func_, b) {}
446 explicit ThreadFuncX0(
const FUNC& func_) : BaseType(func_, None()) {}
447 static void Call(UniquePtr<ThisType>& ptr) {
451 template <
class FUNC,
class T1>
452 struct ThreadFuncX1 :
public Args1<FUNC, T1> {
453 typedef ThreadFuncX1<FUNC, T1> ThisType;
454 typedef Args1<FUNC, T1> BaseType;
456 ThreadFuncX1(
const FUNC& func_,
const T1& arg1_, B b)
457 : BaseType(func_, arg1_, b) {}
458 ThreadFuncX1(
const FUNC& func_,
const T1& arg1_) : BaseType(func_, arg1_, None()) {}
459 static void Call(UniquePtr<ThisType>& ptr) {
460 ptr->func(NLIB_MOVE(ptr->arg1));
463 template <
class FUNC,
class T1,
class T2>
464 struct ThreadFuncX2 :
public Args2<FUNC, T1, T2> {
465 typedef ThreadFuncX2<FUNC, T1, T2> ThisType;
466 typedef Args2<FUNC, T1, T2> BaseType;
468 ThreadFuncX2(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_, B b)
469 : BaseType(func_, arg1_, arg2_, b) {}
470 ThreadFuncX2(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_)
471 : BaseType(func_, arg1_, arg2_, None()) {}
472 static void Call(UniquePtr<ThisType>& ptr) {
473 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2));
476 template <
class FUNC,
class T1,
class T2,
class T3>
477 struct ThreadFuncX3 :
public Args3<FUNC, T1, T2, T3> {
478 typedef ThreadFuncX3<FUNC, T1, T2, T3> ThisType;
479 typedef Args3<FUNC, T1, T2, T3> BaseType;
481 ThreadFuncX3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_, B b)
482 : BaseType(func_, arg1_, arg2_, arg3_, b) {}
483 ThreadFuncX3(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_)
484 : BaseType(func_, arg1_, arg2_, arg3_, None()) {}
485 static void Call(UniquePtr<ThisType>& ptr) {
486 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3));
489 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
490 struct ThreadFuncX4 :
public Args4<FUNC, T1, T2, T3, T4> {
491 typedef ThreadFuncX4<FUNC, T1, T2, T3, T4> ThisType;
492 typedef Args4<FUNC, T1, T2, T3, T4> BaseType;
494 ThreadFuncX4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
495 const T4& arg4_, B b)
496 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, b) {}
497 ThreadFuncX4(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
499 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, None()) {}
500 static void Call(UniquePtr<ThisType>& ptr) {
501 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3),
502 NLIB_MOVE(ptr->arg4));
505 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
506 struct ThreadFuncX5 :
public Args5<FUNC, T1, T2, T3, T4, T5> {
507 typedef ThreadFuncX5<FUNC, T1, T2, T3, T4, T5> ThisType;
508 typedef Args5<FUNC, T1, T2, T3, T4, T5> BaseType;
510 ThreadFuncX5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
511 const T4& arg4_,
const T5& arg5_, B b)
512 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, arg5_, b) {}
513 ThreadFuncX5(
const FUNC& func_,
const T1& arg1_,
const T2& arg2_,
const T3& arg3_,
514 const T4& arg4_,
const T5& arg5_)
515 : BaseType(func_, arg1_, arg2_, arg3_, arg4_, arg5_, None()) {}
516 static void Call(UniquePtr<ThisType>& ptr) {
517 ptr->func(NLIB_MOVE(ptr->arg1), NLIB_MOVE(ptr->arg2), NLIB_MOVE(ptr->arg3),
518 NLIB_MOVE(ptr->arg4), NLIB_MOVE(ptr->arg5));
523 template <
class FUNC>
526 new (std::nothrow) ThreadFuncX0<FUNC>(f,
typename IsSwappable<FUNC>::type()));
527 if (!ptr)
return ENOMEM;
528 return this->StartRaw(settings, ptr);
530 template <
class FUNC>
533 return this->Start(settings, f,
move_tag());
535 template <
class FUNC,
class T1>
538 new (std::nothrow) ThreadFuncX1<FUNC, T1>(f, arg1,
typename ArgType<T1>::type()));
539 if (!ptr)
return ENOMEM;
540 return this->StartRaw(settings, ptr);
542 template <
class FUNC,
class T1>
545 return this->Start(settings, f, arg1,
move_tag());
547 template <
class FUNC,
class T1,
class T2>
551 f, arg1, arg2,
typename ArgType<T2>::type()));
552 if (!ptr)
return ENOMEM;
553 return this->StartRaw(settings, ptr);
555 template <
class FUNC,
class T1,
class T2>
558 return this->Start(settings, f, arg1, arg2,
move_tag());
560 template <
class FUNC,
class T1,
class T2,
class T3>
565 ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3,
typename ArgType<T3>::type()));
566 if (!ptr)
return ENOMEM;
567 return this->StartRaw(settings, ptr);
569 template <
class FUNC,
class T1,
class T2,
class T3>
572 return this->Start(settings, f, arg1, arg2, arg3,
move_tag());
574 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
576 const T3& arg3,
const T4& arg4,
move_tag) {
578 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4,
579 typename ArgType<T4>::type()));
580 if (!ptr)
return ENOMEM;
581 return this->StartRaw(settings, ptr);
583 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
584 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
587 return this->Start(settings, f, arg1, arg2, arg3, arg4,
move_tag());
589 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
591 const T3& arg3,
const T4& arg4,
const T5& arg5,
move_tag) {
593 new (std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(
594 f, arg1, arg2, arg3, arg4, arg5,
typename ArgType<T5>::type()));
595 if (!ptr)
return ENOMEM;
596 return this->StartRaw(settings, ptr);
598 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
599 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
602 return this->Start(settings, f, arg1, arg2, arg3, arg4, arg5,
move_tag());
604 template <
class FUNC>
607 if (!ptr)
return ENOMEM;
608 return this->StartRaw(settings, ptr);
610 template <
class FUNC>
613 return this->Start(settings, f);
615 template <
class FUNC,
class T1>
618 if (!ptr)
return ENOMEM;
619 return this->StartRaw(settings, ptr);
621 template <
class FUNC,
class T1>
624 return this->Start(settings, f, arg1);
626 template <
class FUNC,
class T1,
class T2>
629 ThreadFuncX2<FUNC, T1, T2>(f, arg1, arg2));
630 if (!ptr)
return ENOMEM;
631 return this->StartRaw(settings, ptr);
633 template <
class FUNC,
class T1,
class T2>
636 return this->Start(settings, f, arg1, arg2);
638 template <
class FUNC,
class T1,
class T2,
class T3>
642 new (std::nothrow) ThreadFuncX3<FUNC, T1, T2, T3>(f, arg1, arg2, arg3));
643 if (!ptr)
return ENOMEM;
644 return this->StartRaw(settings, ptr);
646 template <
class FUNC,
class T1,
class T2,
class T3>
647 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3) {
649 return this->Start(settings, f, arg1, arg2, arg3);
651 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
653 const T3& arg3,
const T4& arg4) {
655 new (std::nothrow) ThreadFuncX4<FUNC, T1, T2, T3, T4>(f, arg1, arg2, arg3, arg4));
656 if (!ptr)
return ENOMEM;
657 return this->StartRaw(settings, ptr);
659 template <
class FUNC,
class T1,
class T2,
class T3,
class T4>
660 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4) {
662 return this->Start(settings, f, arg1, arg2, arg3, arg4);
664 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
666 const T3& arg3,
const T4& arg4,
const T5& arg5) {
668 std::nothrow) ThreadFuncX5<FUNC, T1, T2, T3, T4, T5>(f, arg1, arg2, arg3, arg4, arg5));
669 if (!ptr)
return ENOMEM;
670 return this->StartRaw(settings, ptr);
672 template <
class FUNC,
class T1,
class T2,
class T3,
class T4,
class T5>
673 errno_t Start(
const FUNC& f,
const T1& arg1,
const T2& arg2,
const T3& arg3,
const T4& arg4,
676 return this->Start(settings, f, arg1, arg2, arg3, arg4, arg5);
689 struct Thread::Args0<void()> {
691 Args0(
void (*func_)(), X)
693 Args0(
void (*func_)()) : func(func_) {}
701 struct Thread::Args0<void(T1)> {
703 Args0(
void (*func_)(T1), X)
705 Args0(
void (*func_)(T1)) : func(func_) {}
712 template <
class T1,
class T2>
713 struct Thread::Args0<void(T1, T2)> {
715 Args0(
void (*func_)(T1, T2), X)
717 Args0(
void (*func_)(T1, T2)) : func(func_) {}
718 void (*func)(T1, T2);
724 template <
class T1,
class T2,
class T3>
725 struct Thread::Args0<void(T1, T2, T3)> {
727 Args0(
void (*func_)(T1, T2, T3), X)
729 Args0(
void (*func_)(T1, T2, T3)) : func(func_) {}
730 void (*func)(T1, T2, T3);
736 template <
class T1,
class T2,
class T3,
class T4>
737 struct Thread::Args0<void(T1, T2, T3, T4)> {
739 Args0(
void (*func_)(T1, T2, T3, T4), X)
741 Args0(
void (*func_)(T1, T2, T3, T4)) : func(func_) {}
742 void (*func)(T1, T2, T3, T4);
748 template <
class T1,
class T2,
class T3,
class T4,
class T5>
749 struct Thread::Args0<void(T1, T2, T3, T4, T5)> {
751 Args0(
void (*func_)(T1, T2, T3, T4, T5), X)
753 Args0(
void (*func_)(T1, T2, T3, T4, T5)) : func(func_) {}
754 void (*func)(T1, T2, T3, T4, T5);
766 namespace this_thread {
777 return e == 0 ?
id : -1;
791 NLIB_DEFINE_STD_SWAP(::nlib_ns::threading::Thread)
793 #endif // INCLUDE_NN_NLIB_THREADING_THREAD_H_
errno_t GetCpu(int *cpuid) noexcept
呼び出したスレッドが実行されているCPUを取得します。
errno_t YieldThread() noexcept
他のスレッドに制御を譲ります。
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
errno_t Start(const ThreadSettings &settings, const FUNC &f, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, move_tag)
引数を2つもつ関数を別スレッドで実行開始します。 引数を2つ持つこと以外は、引数が1つのバージョンと同じ...
static errno_t Sleep(const TimeSpan &span) noexcept
span の期間だけスリープします。
constexpr Thread() noexcept
デフォルトコンストラクタです。
errno_t Sleep(const TimeSpan &span) noexcept
スリープします。
constexpr ThreadArg(Func func_, T1 arg1_, T2 arg2_, T3 arg3_, T4 arg4_, T5 arg5_)
コンストラクタで構造体のフィールドを初期化します。
C++11の標準ヘッダとなるtype_traitsの代用定義です。 コンパイラや標準ライブラリによってサポートされてい...
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
bool operator!=(const Thread &rhs) noexcept
nlib_thread_equal()を用いてスレッドを比較します。
constexpr ThreadArg()
デフォルトコンストラクタです。
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
T1 arg1
別スレッドで実行する関数に渡されるオブジェクトです。
errno_t Detach() noexcept
スレッドをデタッチします。
Func func
別スレッドで実行する関数へのポインタです。
errno_t GetPriority(int32_t *priority) noexcept
スレッドの優先度を取得します。
nlib_thread GetNativeHandle() const noexcept
実装依存のスレッド識別子を取得します。
T3 arg3
別スレッドで実行する関数に渡されるオブジェクトです。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, move_tag)
引数を5つもつ関数を別スレッドで実行開始します。引数を5つ持つこと以外は、引数が1つのバージョンと同じで...
~Thread() noexcept
デストラクタです。スレッドがJoinされていない場合はJoinします。
errno_t ChangePriority(int32_t priority) noexcept
スレッドの優先度を設定します。
T5 arg5
別スレッドで実行する関数に渡されるオブジェクトです。
void SetDetachState(bool detached) noexcept
デタッチした状態でスレッドを起動するかどうかを設定します。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2)
引数を2つもつ関数を別スレッドで実行開始します。引数を2つ持つこと以外は、引数が1つのバージョンと同じで...
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3)
引数を3つもつ関数を別スレッドで実行開始します。引数を3つ持つこと以外は、引数が1つのバージョンと同じで...
UniquePtrはポインタの所有権を保持し、UniquePtrがスコープから出るときにデストラクタでポインタをDELで指...
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5)
引数を5つもつ関数を別スレッドで実行開始します。引数を5つ持つこと以外は、引数が1つのバージョンと同じで...
std::unique_ptrに相当するクラスが定義されています。
Threadクラスでスレッドを実行するために利用できる構造体です。
void swap(Thread &rhs) noexcept
オブジェクトの内容をスワップします。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, move_tag)
引数を3つもつ関数を別スレッドで実行開始します。 引数を3つ持つこと以外は、引数が1つのバージョンと同じ...
errno_t SetStackSize(int size) noexcept
スタックサイズを設定します。
errno_t Start(const FUNC &f, const T1 &arg1, move_tag)
引数を1つもつ関数を別スレッドで実行開始します。
errno_t StartRaw(UniquePtr< ThArg > &ptr) noexcept
別スレッドの実行を開始します。
int GetPriority() const noexcept
スレッドの優先度を取得します。
nlib_thread_attrをラップするクラスです。必要に応じて自動的にnlib_thread_attr_init()とnlib_thread_attr...
errno_t StartRaw(const ThreadSettings &settings, UniquePtr< ThArg > &ptr) noexcept
別スレッドの実行を開始します。
static errno_t YieldThread() noexcept
nlib_yield()を呼び出します。
errno_t Join() noexcept
スレッドの実行完了を待ちます。
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
空の構造体で、関数の引数をムーブすべきことを示すために利用されます。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
bool operator==(const Thread &rhs) noexcept
nlib_thread_equal()を用いてスレッドを比較します。
bool GetDetachState() const noexcept
デタッチ状態でスレッドを起動する設定かどうかを返します。
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4)
引数を4つもつ関数を別スレッドで実行開始します。引数を4つ持つこと以外は、引数が1つのバージョンと同じで...
errno_t Start(const FUNC &f, const T1 &arg1)
引数を1つもつ関数を別スレッドで実行開始します。
int GetStackSize() const noexcept
設定されているスタックサイズを返します。
errno_t Start(const ThreadSettings &settings, const FUNC &f)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t SetPriority(int priority) noexcept
スレッドの優先度を設定します。優先度の値はプラットフォーム依存です。
nlib_thread_id GetId() noexcept
カレントスレッドのIDを取得します。
errno_t Start(const FUNC &f)
引数を持たない関数を別スレッドで実行開始します。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
size_t GetHardwareConcurrency() noexcept
ハードウェアスレッドの数を返します。
errno_t SetAffinity(uint32_t affinity) noexcept
スレッドのプロセッサアフィニティマスクを設定します。
errno_t SetName(const char *literalString) noexcept
スレッドに名前をつけます。
ThreadArg< T1, T2, T3, T4, T5 > ThisType
この構造体の型へのtypedefです。
errno_t StartRaw(const ThreadSettings &settings, ThreadArg<>::Func func) noexcept
引数を持たない関数を別スレッドで実行開始します。
UniquePtr< ThisType > ArgType
スレッド関数の引数型のtypedefです。
bool IsJoinable() const noexcept
join可能かどうか調べます。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
errno_t SleepMilliSeconds(unsigned int millisec) noexcept
スリープします。
errno_t StartRaw(ThreadArg<>::Func func) noexcept
引数を持たない関数を別スレッドで実行開始します。
T4 arg4
別スレッドで実行する関数に渡されるオブジェクトです。
errno_t GetPriority(int32_t *priority) noexcept
nlib_thread_getpriority()を呼び出して、スレッドの実行優先順位を取得します。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, move_tag)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。
T2 arg2
別スレッドで実行する関数に渡されるオブジェクトです。
errno_t Start(const FUNC &f, move_tag)
引数を持たない関数を別スレッドで実行開始します。 引数を持たないこと以外は、引数が1つのバージョンと同...
errno_t Start(const FUNC &f, const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, move_tag)
引数を4つもつ関数を別スレッドで実行開始します。 引数を4つ持つこと以外は、引数が1つのバージョンと同じ...
errno_t ChangePriority(int32_t priority) noexcept
nlib_thread_setpriority()を呼び出して、スレッドの実行優先順位を設定します。
errno_t Start(const ThreadSettings &settings, const FUNC &f, const T1 &arg1, const T2 &arg2)
スレッドの起動オプションを指定できること以外はそうでないバージョンと同じです。