nlib
ThreadPool.h
Go to the documentation of this file.
1 
2 #pragma once
3 #ifndef INCLUDE_NN_NLIB_THREADING_THREADPOOL_H_
4 #define INCLUDE_NN_NLIB_THREADING_THREADPOOL_H_
5 
6 #include "nn/nlib/Nqueue.h"
7 #include "nn/nlib/UniquePtr.h"
9 
10 NLIB_NAMESPACE_BEGIN
11 namespace threading {
12 
13 namespace detail {
14 class NLIB_VIS_PUBLIC ThPoolTaskBase {
15  public:
16  ThPoolTaskBase() NLIB_NOEXCEPT {}
17  virtual ~ThPoolTaskBase() NLIB_NOEXCEPT {}
18  virtual void operator()() NLIB_NOEXCEPT = 0;
19 
20  private:
21  NLIB_DISALLOW_COPY_AND_ASSIGN(ThPoolTaskBase);
22 };
23 
24 template <class R>
25 class ThPoolTask : public ThPoolTaskBase {
26  public:
27  explicit ThPoolTask(PackagedTask<R()>& task) NLIB_NOEXCEPT { // NOLINT
28  task.swap(m_Task);
29  }
30  virtual ~ThPoolTask() NLIB_NOEXCEPT NLIB_OVERRIDE {}
31  virtual void operator()() NLIB_NOEXCEPT NLIB_OVERRIDE { m_Task(); }
32 
33  private:
34  PackagedTask<R()> m_Task;
36 };
37 } // namespace detail
38 
40  public:
41  ThreadPool() NLIB_NOEXCEPT : m_Status(0) {}
42  NLIB_VIS_PUBLIC errno_t Init(size_t numThreads, const ThreadSettings& settings) NLIB_NOEXCEPT;
43  errno_t Init(size_t numThreads) NLIB_NOEXCEPT {
44  ThreadSettings settings;
45  return this->Init(numThreads, settings);
46  }
47  errno_t Init() NLIB_NOEXCEPT {
48  return this->Init(GetHardwareConcurrency());
49  }
50  NLIB_VIS_PUBLIC ~ThreadPool() NLIB_NOEXCEPT;
51  template <class R, class FUNC>
52  errno_t Submit(Future<R>* future, FUNC& func) NLIB_NOEXCEPT; // NOLINT
53  size_t Count() NLIB_NOEXCEPT { return m_ThreadList.size(); }
54 
55  private:
56  NLIB_VIS_HIDDEN void JoinThreads(Nlist<nlib_thread>& L) NLIB_NOEXCEPT; // NOLINT
57  static NLIB_VIS_HIDDEN void WorkerThread(void* p) NLIB_NOEXCEPT;
58 
59  int32_t m_Status;
60  nlib_mutex m_Lock;
61  Nlist<nlib_thread> m_ThreadList;
63  nlib_cond m_Cond;
65 };
66 
67 template <class R, class FUNC>
68 inline errno_t ThreadPool::Submit(Future<R>* future, FUNC& func) NLIB_NOEXCEPT { // NOLINT
69  PackagedTask<R()> task;
70  errno_t e = task.Init(func);
71  if (e != 0) return e;
72  if (future) {
73  e = task.GetFuture(future);
74  if (e != 0) return e;
75  }
76  UniquePtr<detail::ThPoolTaskBase> pTask(new (std::nothrow) detail::ThPoolTask<R>(task));
77  if (pTask) {
78  e = nlib_mutex_lock(&m_Lock);
79  NLIB_UNUSED(e);
80  NLIB_ASSERT_NOERR(e);
81  bool result = m_WorkQueue.push_back_swap(&pTask);
82  if (result) {
83  // only need to wake up one thread
84  e = nlib_cond_signal(&m_Cond);
85  NLIB_ASSERT_NOERR(e);
86  }
87  e = nlib_mutex_unlock(&m_Lock);
88  NLIB_ASSERT_NOERR(e);
89  return result ? 0 : ENOMEM;
90  } else {
91  return ENOMEM;
92  }
93 }
94 
95 } // namespace threading
96 NLIB_NAMESPACE_END
97 
98 #endif // INCLUDE_NN_NLIB_THREADING_THREADPOOL_H_
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Platform.h:2151
errno_t nlib_cond_signal(nlib_cond *cond)
Resumes the execution of one thread that is waiting for condition variable cond.
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
Definition: Config.h:126
ThreadPool() noexcept
Instantiates the object with default parameters (default constructor). Must be initialized with Init...
Definition: ThreadPool.h:41
#define NLIB_OVERRIDE
Defines override if it is available for use. If not, holds an empty string.
#define NLIB_VIS_HIDDEN
Symbols for functions and classes are not made available outside of the library.
Definition: Platform_unix.h:50
errno_t nlib_mutex_lock(nlib_mutex *mutex)
Locks the specified mutex.
errno_t nlib_mutex_unlock(nlib_mutex *mutex)
Unlocks the specified mutex.
A container-like class similar to std::queue that can store objects that do not have copy constructor...
Definition: Nqueue.h:16
UniquePtr owns the pointer, and when it goes out of scope, the pointer is released by the destructor ...
Definition: UniquePtr.h:96
Defines that class that is corresponding to std::unique_ptr.
The class to wrap nlib_thread_attr. nlib_thread_attr_init() and nlib_thread_attr_destroy() are run au...
Definition: Thread.h:16
errno_t GetFuture(Future< R > *p) noexcept
Sets Future to get the result of execution.
errno_t Init() noexcept
Starts a thread and initializes the thread pool.
Definition: ThreadPool.h:47
pthread_cond_t nlib_cond
The type for a condition variable object.
Class that gets the output of a different thread executing in a thread safe manner. This class is similar to the std::shared_future class of C++11.
Definition: AsyncFileIo.h:13
errno_t Init(size_t numThreads) noexcept
Starts a thread and initializes the thread pool.
Definition: ThreadPool.h:43
size_t GetHardwareConcurrency() noexcept
Returns the number of hardware threads.
Definition: Thread.h:760
pthread_mutex_t nlib_mutex
The type for mutex variables.
Class that wraps a function to run in a different thread, and gets the return value in a thread safe ...
Definition: Future.h:914
#define NLIB_VIS_PUBLIC
Symbols for functions and classes are made available outside of the library.
Definition: Platform_unix.h:51
Implements the Future pattern for multithread programming.
Tasks may be deployed to a pool of threads that have been already created.
Definition: ThreadPool.h:39
errno_t Init(FUNC &func)
Performs initialization.
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:24