<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/en/2171/18/9/_/styles/combined.css?spaceKey=TOP&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://wiki.asterisk.org/wiki/display/TOP/Thread+pool+and+Work+Queues">Thread pool and Work Queues</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~mmichelson">Mark Michelson</a>
    </h4>
        <div id="versionComment">
        <b>Comment:</b>
        Fix a few grammatical problems<br />
    </div>
        <br/>
                         <h4>Changes (2)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >** Resizable, with an API for setting objects that implement custom sizing policies. <br>** Default implementation cleans up idle threads to recover resources after peaks. <br></td></tr>
            <tr><td class="diff-changed-lines" >** Each <span class="diff-changed-words">pool<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">s</span></span> owns a work queue. <br></td></tr>
            <tr><td class="diff-unchanged" >* What is a work queue? <br>{panel} <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{color:white} <br>{panel:title=How Does it Work?|titleBGColor=#2022FF|bgColor=#7788FF} <br></td></tr>
            <tr><td class="diff-changed-lines" >* Basically for any object that has methods that may be called by multiple concurrent threads of execution, organize <span class="diff-changed-words">it<span class="diff-deleted-chars"style="color:#999;background-color:#fdd;text-decoration:line-through;">&#39;</span>s</span> associated state and implement the implementation details in terms of a &quot;work&quot; object and put it on a queue dedicated to that object. <br></td></tr>
            <tr><td class="diff-unchanged" >* A thread pool worker thread obtains a work item from its queue, and this work item is actually a queue of items belonging to your object.  <br>* The worker thread &quot;executes&quot; the work item, ultimately executing your queued work item.  <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/forbidden.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Yes, this is written in a very informal, conversational voice. It was easier getting the info out this way.</td></tr></table></div>


<p><font color="white"><br/>
<div class="panel" style="background-color: #7788FF;border-width: 1px;"><div class="panelHeader" style="border-bottom-width: 1px;background-color: #2022FF;"><b>Thread Pools and Work Queues</b></div><div class="panelContent" style="background-color: #7788FF;">
<ul>
        <li>Rationale:
        <ul>
                <li>Reduce complexity of creating robust multithreaded applications.</li>
                <li>XXX more here!!!!</li>
        </ul>
        </li>
        <li>How:
        <ul>
                <li>Serialize access to shared data, by serializing the operations themselves. That is, don't share the data.</li>
        </ul>
        </li>
        <li>Wha?
        <ul>
                <li>Okay.. it breaks down something like this...</li>
        </ul>
        </li>
</ul>
</div></div></font></p>


<p><font color="white"><br/>
<div class="panel" style="background-color: #7788FF;border-width: 1px;"><div class="panelHeader" style="border-bottom-width: 1px;background-color: #2022FF;"><b>Thread Pools</b></div><div class="panelContent" style="background-color: #7788FF;">
<ul>
        <li>Familiar concept. A managed collection of threads for performing work.</li>
        <li>Asterisk SCF thread pool details.
        <ul>
                <li>Resizable, with an API for setting objects that implement custom sizing policies.</li>
                <li>Default implementation cleans up idle threads to recover resources after peaks.</li>
                <li>Each pool owns a work queue.</li>
        </ul>
        </li>
        <li>What is a work queue?</li>
</ul>
</div></div></font></p>

<p><font color="white"><br/>
<div class="panel" style="background-color: #7788FF;border-width: 1px;"><div class="panelHeader" style="border-bottom-width: 1px;background-color: #2022FF;"><b>Work Queues</b></div><div class="panelContent" style="background-color: #7788FF;">
<ul>
        <li>A work queue is a collection of "Work", which is basically an object that implements the Work interface.</li>
        <li>Here is the kicker. A Work object may itself be a collection of Work objects.</li>
        <li>Voila, we have a mechanism for queuing work for a set of data in a way that it will only ever be acted on by a single thread at a time.</li>
        <li>Implications:
        <ul>
                <li>All Ice method and methods that respond to potentially concurrent events must be implemented in terms of Work object instances.</li>
                <li>For Ice, AMI and AMD tends to get used a lot.</li>
                <li>Code is organized differently. A little awkward at first but quickly feels natural.</li>
        </ul>
        </li>
</ul>
</div></div></font></p>

<p><font color="white"><br/>
<div class="panel" style="background-color: #7788FF;border-width: 1px;"><div class="panelHeader" style="border-bottom-width: 1px;background-color: #2022FF;"><b>How Does it Work?</b></div><div class="panelContent" style="background-color: #7788FF;">
<ul>
        <li>Basically for any object that has methods that may be called by multiple concurrent threads of execution, organize its associated state and implement the implementation details in terms of a "work" object and put it on a queue dedicated to that object.</li>
        <li>A thread pool worker thread obtains a work item from its queue, and this work item is actually a queue of items belonging to your object.</li>
        <li>The worker thread "executes" the work item, ultimately executing your queued work item.</li>
        <li>As the work items for a single object are in a single work queue item and that work queue item may only be processed by a single thread, you have serialized access without mutexes and without concern of race conditions and deadlock.</li>
        <li>Locks or no locks, it is a great way to avoid race conditions by organizing data access.</li>
</ul>
</div></div></font></p>

<p><font color="white"><br/>
<div class="panel" style="background-color: #7788FF;border-width: 1px;"><div class="panelHeader" style="border-bottom-width: 1px;background-color: #2022FF;"><b>Anatomy of a Work Item</b></div><div class="panelContent" style="background-color: #7788FF;">
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="theme: Confluence; brush: java; gutter: false">class MyWorkItem : public AsteriskSCF::System::WorkQueue::V1::Work
{
public:
    MyWorkItem(const StateBeingWorkedOnPtr&amp; state) :
       mState(state)
    { }

    void execute() 
    { /* Do some stuff to state, possibly enqueuing another work item */ }
};</pre>
</div></div>
<p><em>a graphic would be handy</em></p>
</div></div></font></p>


<p><font color="white"><br/>
<div class="panel" style="background-color: #7788FF;border-width: 1px;"><div class="panelHeader" style="border-bottom-width: 1px;background-color: #2022FF;"><b>In the Wild</b></div><div class="panelContent" style="background-color: #7788FF;">
<ul>
        <li>SIP Session Gateway.</li>
</ul>
</div></div></font></p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;" class="grey">
                        <a href="https://wiki.asterisk.org/wiki/users/removespacenotification.action?spaceKey=TOP">Stop watching space</a>
            <span style="padding: 0px 5px;">|</span>
                <a href="https://wiki.asterisk.org/wiki/users/editmyemailsettings.action">Change email notification preferences</a>
</div>
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Thread+pool+and+Work+Queues">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=19006261&revisedVersion=3&originalVersion=2">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Thread+pool+and+Work+Queues?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>