Angelscript/docs/manual/doc_adv_concurrent.html

183 lines
13 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.18"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Concurrent scripts</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">AngelScript
</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.18 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('doc_adv_concurrent.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">Concurrent scripts </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>The script engine can run multiple scripts in parallel, i.e. concurrent scripts. This can be done easily using <a class="el" href="doc_adv_multithread.html">multithreading</a> where each thread runs its own script context, but this article is going to explain how it is done without multithreading.</p>
<p>In order to execute multiple scripts in parallel, each script must have it's own <a class="el" href="classas_i_script_context.html">asIScriptContext</a>, where the context is set up as for a <a class="el" href="doc_call_script_func.html">normal function call</a>. Then the application needs to set a timeout for each context. When the timeout is reached, the context should be <a class="el" href="classas_i_script_context.html#ad4ac8be3586c46069b5870e40c86544a">suspended</a>, so that the next context can execute for a while.</p>
<p>Here's a very simple example of how this can be done:</p>
<div class="fragment"><div class="line"><span class="comment">// The contexts have already been prepared before this function is called</span></div>
<div class="line"><span class="keywordtype">void</span> ExecuteScripts(std::vector&lt;asIScriptContext *&gt; contexts)</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// This function will run until all scripts have completed</span></div>
<div class="line"> <span class="keywordflow">while</span>( contexts.size() &gt; 0 )</div>
<div class="line"> {</div>
<div class="line"> <span class="keywordflow">for</span>( <a class="code" href="angelscript_8h.html#ac8186f029686800b7ce36bde4a55c815">asUINT</a> n = 0; n &lt; contexts.size(); n++ )</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// Set a 10 millisecond timeout for this context</span></div>
<div class="line"> SetTimeoutForContext(contexts[n], 10);</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Resume the execution of this context by calling Execute</span></div>
<div class="line"> <span class="keywordtype">int</span> r = contexts[n]-&gt;Execute();</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Remove the timeout so it won&#39;t be triggered accidentally</span></div>
<div class="line"> RemoveTimeoutForContext();</div>
<div class="line"> </div>
<div class="line"> <span class="comment">// Determine if the script completed, or was timed out</span></div>
<div class="line"> <span class="keywordflow">if</span>( r == <a class="code" href="angelscript_8h.html#a867f14b4137dd4602fda1e616b217a69a7b5644be315c46f2fa44f032731242c7">asEXECUTION_SUSPENDED</a> )</div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// The script will continue in the next iteration</span></div>
<div class="line"> }</div>
<div class="line"> <span class="keywordflow">else</span></div>
<div class="line"> {</div>
<div class="line"> <span class="comment">// The script has completed the execution, so we take it out of the list of scripts</span></div>
<div class="line"> contexts[n--] = contexts.back();</div>
<div class="line"> contexts.pop_back();</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line"> }</div>
<div class="line">}</div>
</div><!-- fragment --><p>The application can manage the execution of the scripts in a simple round-robin fashion, where each script gets equal amount of execution time, or a more intricate management algorithm can be built, e.g. to give more execution time to high priority scripts etc.</p>
<p>The time out function, i.e. SetTimeoutForContext in the example above, can be implemented in two different ways. Through the use of <a class="el" href="classas_i_script_context.html#ae2747f643bf9a07364f922c460ef57dd">line callbacks</a>, where the context will invoke the callback for each statement in the script. The callback can then check if the timeout limit has been reached and suspend the context.</p>
<p>The other way is through the use of a timeout thread, where the thread simply sleeps until the timeout limit has been reached, and when the thread wakes up it suspends the context (if it is still running).</p>
<p>The timeout thread is probably the easiest to implement, and also doesn't impact the performance as much as the line callback. The line callback may still have to be used if the target OS doesn't support multithreading though.</p>
<p>Here's a simple example of how to implement the timeout function with a separate thread:</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> HANDLE thread_handle = 0;</div>
<div class="line"><span class="keyword">static</span> <a class="code" href="classas_i_script_context.html">asIScriptContext</a> *thread_ctx;</div>
<div class="line"> </div>
<div class="line">DWORD WINAPI TimeoutThread(<span class="keywordtype">void</span> *sleeptime)</div>
<div class="line">{</div>
<div class="line"> Sleep(*<span class="keyword">reinterpret_cast&lt;</span><span class="keywordtype">int</span>*<span class="keyword">&gt;</span>(sleeptime));</div>
<div class="line"> <span class="keywordflow">if</span>( thread_ctx )</div>
<div class="line"> thread_ctx-&gt;<a class="code" href="classas_i_script_context.html#ad4ac8be3586c46069b5870e40c86544a">Suspend</a>();</div>
<div class="line"> </div>
<div class="line"> <span class="keywordflow">return</span> 0;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> SetTimeoutForContext(<a class="code" href="classas_i_script_context.html">asIScriptContext</a> *ctx, <span class="keywordtype">int</span> milliseconds)</div>
<div class="line">{</div>
<div class="line"> thread_ctx = ctx;</div>
<div class="line"> thread_handle = CreateThread(0, 50, TimeoutThread, <span class="keyword">reinterpret_cast&lt;</span><span class="keywordtype">void</span>*<span class="keyword">&gt;</span>(&amp;milliseconds), 0, 0);</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> RemoveTimeoutForContext()</div>
<div class="line">{</div>
<div class="line"> <span class="comment">// TerminateThread should be used with extreme care, but in this </span></div>
<div class="line"> <span class="comment">// case the TimeoutThread can&#39;t do any harm even if interrupted </span></div>
<div class="line"> <span class="comment">// in the middle of the execution</span></div>
<div class="line"> TerminateThread(thread_handle, 0);</div>
<div class="line"> thread_handle = 0;</div>
<div class="line">}</div>
</div><!-- fragment --><p>Observe that the routines for multithreading usually differ a lot depending on the target system. The above code is for Windows and will most likely require adaption to work on any other system.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="doc_addon_ctxmgr.html">Context manager</a>, <a class="el" href="doc_samples_concurrent.html">Concurrent scripts</a>, <a class="el" href="doc_adv_coroutine.html">Co-routines</a> </dd></dl>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<div class="ttc" id="aclassas_i_script_context_html"><div class="ttname"><a href="classas_i_script_context.html">asIScriptContext</a></div><div class="ttdoc">The interface to the virtual machine.</div><div class="ttdef"><b>Definition:</b> angelscript.h:2717</div></div>
<div class="ttc" id="aangelscript_8h_html_a867f14b4137dd4602fda1e616b217a69a7b5644be315c46f2fa44f032731242c7"><div class="ttname"><a href="angelscript_8h.html#a867f14b4137dd4602fda1e616b217a69a7b5644be315c46f2fa44f032731242c7">asEXECUTION_SUSPENDED</a></div><div class="ttdeci">@ asEXECUTION_SUSPENDED</div><div class="ttdoc">The execution is suspended and can be resumed.</div><div class="ttdef"><b>Definition:</b> angelscript.h:400</div></div>
<div class="ttc" id="aclassas_i_script_context_html_ad4ac8be3586c46069b5870e40c86544a"><div class="ttname"><a href="classas_i_script_context.html#ad4ac8be3586c46069b5870e40c86544a">asIScriptContext::Suspend</a></div><div class="ttdeci">virtual int Suspend()=0</div><div class="ttdoc">Suspends the execution, which can then be resumed by calling Execute again.</div></div>
<div class="ttc" id="aangelscript_8h_html_ac8186f029686800b7ce36bde4a55c815"><div class="ttname"><a href="angelscript_8h.html#ac8186f029686800b7ce36bde4a55c815">asUINT</a></div><div class="ttdeci">unsigned int asUINT</div><div class="ttdoc">32 bit unsigned integer</div><div class="ttdef"><b>Definition:</b> angelscript.h:600</div></div>
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated on Sat Dec 5 2020 23:20:24 for AngelScript by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.18 </li>
</ul>
</div>
</body>
</html>