Thread.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. //
  2. // Thread.h
  3. //
  4. // Library: Foundation
  5. // Package: Threading
  6. // Module: Thread
  7. //
  8. // Definition of the Thread class.
  9. //
  10. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // SPDX-License-Identifier: BSL-1.0
  14. //
  15. #ifndef Foundation_Thread_INCLUDED
  16. #define Foundation_Thread_INCLUDED
  17. #include "Poco/Foundation.h"
  18. #include "Poco/Event.h"
  19. #include "Poco/Mutex.h"
  20. #if defined(POCO_OS_FAMILY_WINDOWS)
  21. #if defined(_WIN32_WCE)
  22. #include "Poco/Thread_WINCE.h"
  23. #else
  24. #include "Poco/Thread_WIN32.h"
  25. #endif
  26. #elif defined(POCO_VXWORKS)
  27. #include "Poco/Thread_VX.h"
  28. #else
  29. #include "Poco/Thread_POSIX.h"
  30. #endif
  31. namespace Poco {
  32. class Runnable;
  33. class ThreadLocalStorage;
  34. class Foundation_API Thread: private ThreadImpl
  35. /// This class implements a platform-independent
  36. /// wrapper to an operating system thread.
  37. ///
  38. /// Every Thread object gets a unique (within
  39. /// its process) numeric thread ID.
  40. /// Furthermore, a thread can be assigned a name.
  41. /// The name of a thread can be changed at any time.
  42. {
  43. public:
  44. typedef ThreadImpl::TIDImpl TID;
  45. using ThreadImpl::Callable;
  46. enum Priority
  47. /// Thread priorities.
  48. {
  49. PRIO_LOWEST = PRIO_LOWEST_IMPL, /// The lowest thread priority.
  50. PRIO_LOW = PRIO_LOW_IMPL, /// A lower than normal thread priority.
  51. PRIO_NORMAL = PRIO_NORMAL_IMPL, /// The normal thread priority.
  52. PRIO_HIGH = PRIO_HIGH_IMPL, /// A higher than normal thread priority.
  53. PRIO_HIGHEST = PRIO_HIGHEST_IMPL /// The highest thread priority.
  54. };
  55. enum Policy
  56. {
  57. POLICY_DEFAULT = POLICY_DEFAULT_IMPL
  58. };
  59. Thread();
  60. /// Creates a thread. Call start() to start it.
  61. Thread(const std::string& name);
  62. /// Creates a named thread. Call start() to start it.
  63. ~Thread();
  64. /// Destroys the thread.
  65. int id() const;
  66. /// Returns the unique thread ID of the thread.
  67. TID tid() const;
  68. /// Returns the native thread ID of the thread.
  69. std::string name() const;
  70. /// Returns the name of the thread.
  71. std::string getName() const;
  72. /// Returns the name of the thread.
  73. void setName(const std::string& name);
  74. /// Sets the name of the thread.
  75. void setPriority(Priority prio);
  76. /// Sets the thread's priority.
  77. ///
  78. /// Some platform only allow changing a thread's priority
  79. /// if the process has certain privileges.
  80. Priority getPriority() const;
  81. /// Returns the thread's priority.
  82. void setOSPriority(int prio, int policy = POLICY_DEFAULT);
  83. /// Sets the thread's priority, using an operating system specific
  84. /// priority value. Use getMinOSPriority() and getMaxOSPriority() to
  85. /// obtain mininum and maximum priority values. Additionally,
  86. /// a scheduling policy can be specified. The policy is currently
  87. /// only used on POSIX platforms where the values SCHED_OTHER (default),
  88. /// SCHED_FIFO and SCHED_RR are supported.
  89. int getOSPriority() const;
  90. /// Returns the thread's priority, expressed as an operating system
  91. /// specific priority value.
  92. ///
  93. /// May return 0 if the priority has not been explicitly set.
  94. static int getMinOSPriority(int policy = POLICY_DEFAULT);
  95. /// Returns the minimum operating system-specific priority value,
  96. /// which can be passed to setOSPriority() for the given policy.
  97. static int getMaxOSPriority(int policy = POLICY_DEFAULT);
  98. /// Returns the maximum operating system-specific priority value,
  99. /// which can be passed to setOSPriority() for the given policy.
  100. void setStackSize(int size);
  101. /// Sets the thread's stack size in bytes.
  102. /// Setting the stack size to 0 will use the default stack size.
  103. /// Typically, the real stack size is rounded up to the nearest
  104. /// page size multiple.
  105. int getStackSize() const;
  106. /// Returns the thread's stack size in bytes.
  107. /// If the default stack size is used, 0 is returned.
  108. void start(Runnable& target);
  109. /// Starts the thread with the given target.
  110. ///
  111. /// Note that the given Runnable object must remain
  112. /// valid during the entire lifetime of the thread, as
  113. /// only a reference to it is stored internally.
  114. void start(Callable target, void* pData = 0);
  115. /// Starts the thread with the given target and parameter.
  116. template <class Functor>
  117. void startFunc(Functor fn)
  118. /// Starts the thread with the given functor object or lambda.
  119. {
  120. startImpl(new FunctorRunnable<Functor>(fn));
  121. }
  122. void join();
  123. /// Waits until the thread completes execution.
  124. /// If multiple threads try to join the same
  125. /// thread, the result is undefined.
  126. void join(long milliseconds);
  127. /// Waits for at most the given interval for the thread
  128. /// to complete. Throws a TimeoutException if the thread
  129. /// does not complete within the specified time interval.
  130. bool tryJoin(long milliseconds);
  131. /// Waits for at most the given interval for the thread
  132. /// to complete. Returns true if the thread has finished,
  133. /// false otherwise.
  134. bool isRunning() const;
  135. /// Returns true if the thread is running.
  136. static bool trySleep(long milliseconds);
  137. /// Starts an interruptible sleep. When trySleep() is called,
  138. /// the thread will remain suspended until:
  139. /// - the timeout expires or
  140. /// - wakeUp() is called
  141. ///
  142. /// Function returns true if sleep attempt was completed, false
  143. /// if sleep was interrupted by a wakeUp() call.
  144. /// A frequent scenario where trySleep()/wakeUp() pair of functions
  145. /// is useful is with threads spending most of the time idle,
  146. /// with periodic activity between the idle times; trying to sleep
  147. /// (as opposed to sleeping) allows immediate ending of idle thread
  148. /// from the outside.
  149. ///
  150. /// The trySleep() and wakeUp() calls should be used with
  151. /// understanding that the suspended state is not a true sleep,
  152. /// but rather a state of waiting for an event, with timeout
  153. /// expiration. This makes order of calls significant; calling
  154. /// wakeUp() before calling trySleep() will prevent the next
  155. /// trySleep() call to actually suspend the thread (which, in
  156. /// some scenarios, may be desirable behavior).
  157. void wakeUp();
  158. /// Wakes up the thread which is in the state of interruptible
  159. /// sleep. For threads that are not suspended, calling this
  160. /// function has the effect of preventing the subsequent
  161. /// trySleep() call to put thread in a suspended state.
  162. static void sleep(long milliseconds);
  163. /// Suspends the current thread for the specified
  164. /// amount of time.
  165. static void yield();
  166. /// Yields cpu to other threads.
  167. static Thread* current();
  168. /// Returns the Thread object for the currently active thread.
  169. /// If the current thread is the main thread, 0 is returned.
  170. static TID currentTid();
  171. /// Returns the native thread ID for the current thread.
  172. protected:
  173. ThreadLocalStorage& tls();
  174. /// Returns a reference to the thread's local storage.
  175. void clearTLS();
  176. /// Clears the thread's local storage.
  177. std::string makeName();
  178. /// Creates a unique name for a thread.
  179. static int uniqueId();
  180. /// Creates and returns a unique id for a thread.
  181. template <class Functor>
  182. class FunctorRunnable: public Runnable
  183. {
  184. public:
  185. FunctorRunnable(const Functor& functor):
  186. _functor(functor)
  187. {
  188. }
  189. ~FunctorRunnable()
  190. {
  191. }
  192. void run()
  193. {
  194. _functor();
  195. }
  196. private:
  197. Functor _functor;
  198. };
  199. private:
  200. Thread(const Thread&);
  201. Thread& operator = (const Thread&);
  202. int _id;
  203. std::string _name;
  204. ThreadLocalStorage* _pTLS;
  205. Event _event;
  206. mutable FastMutex _mutex;
  207. friend class ThreadLocalStorage;
  208. friend class PooledThread;
  209. };
  210. //
  211. // inlines
  212. //
  213. inline Thread::TID Thread::tid() const
  214. {
  215. return tidImpl();
  216. }
  217. inline int Thread::id() const
  218. {
  219. return _id;
  220. }
  221. inline std::string Thread::name() const
  222. {
  223. FastMutex::ScopedLock lock(_mutex);
  224. return _name;
  225. }
  226. inline std::string Thread::getName() const
  227. {
  228. FastMutex::ScopedLock lock(_mutex);
  229. return _name;
  230. }
  231. inline bool Thread::isRunning() const
  232. {
  233. return isRunningImpl();
  234. }
  235. inline void Thread::sleep(long milliseconds)
  236. {
  237. sleepImpl(milliseconds);
  238. }
  239. inline void Thread::yield()
  240. {
  241. yieldImpl();
  242. }
  243. inline Thread* Thread::current()
  244. {
  245. return static_cast<Thread*>(currentImpl());
  246. }
  247. inline void Thread::setOSPriority(int prio, int policy)
  248. {
  249. setOSPriorityImpl(prio, policy);
  250. }
  251. inline int Thread::getOSPriority() const
  252. {
  253. return getOSPriorityImpl();
  254. }
  255. inline int Thread::getMinOSPriority(int policy)
  256. {
  257. return ThreadImpl::getMinOSPriorityImpl(policy);
  258. }
  259. inline int Thread::getMaxOSPriority(int policy)
  260. {
  261. return ThreadImpl::getMaxOSPriorityImpl(policy);
  262. }
  263. inline void Thread::setStackSize(int size)
  264. {
  265. setStackSizeImpl(size);
  266. }
  267. inline int Thread::getStackSize() const
  268. {
  269. return getStackSizeImpl();
  270. }
  271. inline Thread::TID Thread::currentTid()
  272. {
  273. return currentTidImpl();
  274. }
  275. } // namespace Poco
  276. #endif // Foundation_Thread_INCLUDED