\hypertarget{class_qore_1_1_thread_1_1_thread_pool}{}\doxysection{Qore\+::Thread\+::Thread\+Pool Class Reference}
\label{class_qore_1_1_thread_1_1_thread_pool}\index{Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}}


This class defines a thread pool that grows and shrinks dynamically within user-\/defined limits according to the task load placed on it.  




{\ttfamily \#include $<$QC\+\_\+\+Thread\+Pool.\+dox.\+h$>$}

\doxysubsection*{Public Member Functions}
\begin{DoxyCompactItemize}
\item 
\mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a23a918821c73265f97125619d1f71cdc}{constructor}} (\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} \mbox{\hyperlink{group__list__functions_ga67a04aa765442456f353bf8b38b50e0e}{max}}=0, \mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} minidle=0, \mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} maxidle=0, timeout release\+\_\+ms=5s)
\begin{DoxyCompactList}\small\item\em creates the pool with the given parameters; idle worker threads are started immediately if necessary \end{DoxyCompactList}\item 
\mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_ac945632df4f836f3f0de18cc3bd545fe}{destructor}} ()
\begin{DoxyCompactList}\small\item\em destroys the pool; any worker threads are detached and pending tasks not yet executed are canceled; to wait for all worker threads to complete, call \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a7dcb42215303978ddee052d32dca8bb1}{Thread\+Pool\+::stop\+Wait()}} first \end{DoxyCompactList}\item 
\mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_afa052186d36018d008fafc917f54dd74}{stop}} ()
\begin{DoxyCompactList}\small\item\em stops the thread pool and returns immediately; queued tasks are canceled \end{DoxyCompactList}\item 
\mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a7dcb42215303978ddee052d32dca8bb1}{stop\+Wait}} ()
\begin{DoxyCompactList}\small\item\em stops the thread pool and does not return until all submitted tasks have been executed and all worker threads have been stopped \end{DoxyCompactList}\item 
\mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a9b6fcc0e377c68eec2d7e36535700c5f}{submit}} (code task, \+\_\+\+\_\+7\+\_\+ code cancel)
\begin{DoxyCompactList}\small\item\em submit a task to the pool \end{DoxyCompactList}\item 
\mbox{\hyperlink{group__type__conversion__functions_gacf16b4126b795f4b6933ef3425cadae3}{string}} \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a9d36ff6e50ed7e6e2798791151913da1}{to\+String}} ()
\begin{DoxyCompactList}\small\item\em returns a description of the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} \end{DoxyCompactList}\end{DoxyCompactItemize}


\doxysubsection{Detailed Description}
This class defines a thread pool that grows and shrinks dynamically within user-\/defined limits according to the task load placed on it. 

The \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} can also pre-\/allocate idle threads for quickly allocating threads to tasks submitted through \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a9b6fcc0e377c68eec2d7e36535700c5f}{Thread\+Pool\+::submit()}} for cases when very low latency is required (for example, for allocating already waiting threads to incoming \mbox{\hyperlink{class_qore_1_1_socket}{Socket}} connections).

A worker thread is started while the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} is running that waits for tasks in an internal task queue and allocates the tasks to worker threads. If an idle thread is available, the task is submitted to that thread immediately, otherwise, if the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} is not already at maximum capacity (the {\itshape max} argument to \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a23a918821c73265f97125619d1f71cdc}{Thread\+Pool\+::constructor()}}), a new thread is started and the task is allocated to the new thread. Otherwise, the task will block until a thread becomes free, at which time the task is allocated to the newly-\/freed worker thread.

When a worker thread has no more tasks to execute, it will either be returned to the pool to wait in an idle state if possible, or it will terminate. Threads are returned to the idle pool if there are fewer than {\itshape maxidle} threads in the idle pool already or if there are more tasks in the queue than idle threads.

Thread\+Pools downscale over time when demand is lower according to the {\itshape release\+\_\+ms} argument to \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a23a918821c73265f97125619d1f71cdc}{Thread\+Pool\+::constructor()}}; when there more than {\itshape minidle} threads in the idle pool, then for each time period defined by {\itshape release\+\_\+ms}, a single thread in the idle pool is released until the number of threads in the idle pool reaches {\itshape minidle}.

Therefore the {\itshape minidle} argument defines the \char`\"{}ground state\char`\"{} of the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} (how many idle threads are waiting for tasks), and the {\itshape release\+\_\+ms} argument defines the period in which the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} returns to its ground state after demand for threads results in a condition where there are temporarily more than {\itshape minidle} threads in the idle pool.

If the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} is stopped when tasks are still in the queue, then any cancellation \mbox{\hyperlink{expressions_closure}{closure}} or \mbox{\hyperlink{expressions_call_reference}{call reference}} for the task is executed; see \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a9b6fcc0e377c68eec2d7e36535700c5f}{Thread\+Pool\+::submit()}} for more information.

\begin{DoxyParagraph}{Restrictions\+:}
\mbox{\hyperlink{group__parse__options_gade963e1fbbd1f5b2c777df7221512a1b}{Qore\+::\+PO\+\_\+\+NO\+\_\+\+THREAD\+\_\+\+CLASSES}}
\end{DoxyParagraph}
\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{ThreadPool tp(10, 2, 4);}

\end{DoxyCode}

\end{DoxyParagraph}
\begin{DoxySince}{Since}
Qore 0.\+8.\+8 
\end{DoxySince}


\doxysubsection{Member Function Documentation}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_thread_pool_a23a918821c73265f97125619d1f71cdc}\label{class_qore_1_1_thread_1_1_thread_pool_a23a918821c73265f97125619d1f71cdc}} 
\index{Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}!constructor@{constructor}}
\index{constructor@{constructor}!Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}}
\doxysubsubsection{\texorpdfstring{constructor()}{constructor()}}
{\footnotesize\ttfamily Qore\+::\+Thread\+::\+Thread\+Pool\+::constructor (\begin{DoxyParamCaption}\item[{\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}}}]{max = {\ttfamily 0},  }\item[{\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}}}]{minidle = {\ttfamily 0},  }\item[{\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}}}]{maxidle = {\ttfamily 0},  }\item[{timeout}]{release\+\_\+ms = {\ttfamily 5s} }\end{DoxyParamCaption})}



creates the pool with the given parameters; idle worker threads are started immediately if necessary 

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{ThreadPool tp(10, 2, 4);}

\end{DoxyCode}

\end{DoxyParagraph}
When worker threads complete, the thread is returned to the pool if there are less than {\itshape minidle} threads in the idle list or there are more tasks in the queue than the number of idle threads.


\begin{DoxyParams}{Parameters}
{\em max} & the maximum number of threads in the pool \\
\hline
{\em minidle} & the minimum number of free idle threads to keep ready \\
\hline
{\em maxidle} & the maximum number of idle threads to keep ready \\
\hline
{\em release\+\_\+ms} & this value gives the delay in terminating single idle threads when {\itshape maxidle} \texorpdfstring{$>$}{>} {\itshape minidle} and there are more than {\itshape minidle} threads in the idle pool; for example, if {\itshape release\+\_\+ms} = {\ttfamily 10s} then when there are more than {\itshape minidle} threads in the idle pool, every 10 seconds an idle thread is terminated until there are {\itshape minidle} threads in the pool. Note that like all Qore functions and methods taking timeout values, a \mbox{\hyperlink{basic_data_types_relative_dates}{relative date/time value}} can be used to make the units clear (i.\+e. {\ttfamily 2m} = two minutes, etc.)\\
\hline
\end{DoxyParams}

\begin{DoxyExceptions}{Exceptions}
{\em THREADPOOL-\/\+ERROR} & minidle \texorpdfstring{$>$}{>} max, maxidle \texorpdfstring{$>$}{>} max or minidle \texorpdfstring{$>$}{>} maxidle, or release\+\_\+ms \texorpdfstring{$<$}{<} 0 \\
\hline
\end{DoxyExceptions}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_thread_pool_ac945632df4f836f3f0de18cc3bd545fe}\label{class_qore_1_1_thread_1_1_thread_pool_ac945632df4f836f3f0de18cc3bd545fe}} 
\index{Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}!destructor@{destructor}}
\index{destructor@{destructor}!Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}}
\doxysubsubsection{\texorpdfstring{destructor()}{destructor()}}
{\footnotesize\ttfamily Qore\+::\+Thread\+::\+Thread\+Pool\+::destructor (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



destroys the pool; any worker threads are detached and pending tasks not yet executed are canceled; to wait for all worker threads to complete, call \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a7dcb42215303978ddee052d32dca8bb1}{Thread\+Pool\+::stop\+Wait()}} first 

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{delete tp;}

\end{DoxyCode}
 
\end{DoxyParagraph}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_thread_pool_afa052186d36018d008fafc917f54dd74}\label{class_qore_1_1_thread_1_1_thread_pool_afa052186d36018d008fafc917f54dd74}} 
\index{Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}!stop@{stop}}
\index{stop@{stop}!Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}}
\doxysubsubsection{\texorpdfstring{stop()}{stop()}}
{\footnotesize\ttfamily Qore\+::\+Thread\+::\+Thread\+Pool\+::stop (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



stops the thread pool and returns immediately; queued tasks are canceled 

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{tp.stop();}

\end{DoxyCode}

\end{DoxyParagraph}
This method detaches all worker threads immediately, stops the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}}, and returns immediately; after this method has been executed once no more tasks can be submitted to the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}}.

Queued tasks not yet processed by a worker thread are canceled.

\begin{DoxyNote}{Note}
if any worker threads are still running; they are detached from the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} and terminate independently from the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}}
\end{DoxyNote}
\begin{DoxySeeAlso}{See also}
\mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_a7dcb42215303978ddee052d32dca8bb1}{Thread\+Pool\+::stop\+Wait()}} 
\end{DoxySeeAlso}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_thread_pool_a7dcb42215303978ddee052d32dca8bb1}\label{class_qore_1_1_thread_1_1_thread_pool_a7dcb42215303978ddee052d32dca8bb1}} 
\index{Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}!stopWait@{stopWait}}
\index{stopWait@{stopWait}!Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}}
\doxysubsubsection{\texorpdfstring{stopWait()}{stopWait()}}
{\footnotesize\ttfamily Qore\+::\+Thread\+::\+Thread\+Pool\+::stop\+Wait (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



stops the thread pool and does not return until all submitted tasks have been executed and all worker threads have been stopped 

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{tp.stopWait();}

\end{DoxyCode}

\end{DoxyParagraph}
This method does not return until the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} has been stopped and all worker threads have also been stopped. After this method has been executed once no more tasks can be submitted to the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}}.

\begin{DoxySeeAlso}{See also}
\mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool_afa052186d36018d008fafc917f54dd74}{Thread\+Pool\+::stop()}} 
\end{DoxySeeAlso}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_thread_pool_a9b6fcc0e377c68eec2d7e36535700c5f}\label{class_qore_1_1_thread_1_1_thread_pool_a9b6fcc0e377c68eec2d7e36535700c5f}} 
\index{Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}!submit@{submit}}
\index{submit@{submit}!Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}}
\doxysubsubsection{\texorpdfstring{submit()}{submit()}}
{\footnotesize\ttfamily Qore\+::\+Thread\+::\+Thread\+Pool\+::submit (\begin{DoxyParamCaption}\item[{code}]{task,  }\item[{\+\_\+\+\_\+7\+\_\+ code}]{cancel }\end{DoxyParamCaption})}



submit a task to the pool 

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{tp.submit(sub () \{ call\_function(arg); \});}

\end{DoxyCode}

\end{DoxyParagraph}

\begin{DoxyParams}{Parameters}
{\em task} & the \mbox{\hyperlink{expressions_closure}{closure}} or \mbox{\hyperlink{expressions_call_reference}{call reference}} to execute \\
\hline
{\em cancel} & an optional \mbox{\hyperlink{expressions_closure}{closure}} or \mbox{\hyperlink{expressions_call_reference}{call reference}} to execute if the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} is stopped before the task can be executed; note that cancellation code is run serially for each task in order of submission in the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}}\textquotesingle{}s worker thread after the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} has been shut down \\
\hline
\end{DoxyParams}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_thread_pool_a9d36ff6e50ed7e6e2798791151913da1}\label{class_qore_1_1_thread_1_1_thread_pool_a9d36ff6e50ed7e6e2798791151913da1}} 
\index{Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}!toString@{toString}}
\index{toString@{toString}!Qore::Thread::ThreadPool@{Qore::Thread::ThreadPool}}
\doxysubsubsection{\texorpdfstring{toString()}{toString()}}
{\footnotesize\ttfamily \mbox{\hyperlink{group__type__conversion__functions_gacf16b4126b795f4b6933ef3425cadae3}{string}} Qore\+::\+Thread\+::\+Thread\+Pool\+::to\+String (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



returns a description of the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} 

\begin{DoxyParagraph}{Code Flags\+:}
\mbox{\hyperlink{code_flags_CONSTANT}{CONSTANT}}
\end{DoxyParagraph}
\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{string desc = tp.toString();}

\end{DoxyCode}

\end{DoxyParagraph}
\begin{DoxyReturn}{Returns}
a description of the \mbox{\hyperlink{class_qore_1_1_thread_1_1_thread_pool}{Thread\+Pool}} 
\end{DoxyReturn}
