Thread.h 8.7 KB

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