<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.15">
  <compounddef id="md__docs_fibers" kind="page">
    <compoundname>md_Docs_fibers</compoundname>
    <title>Fibers</title>
    <briefdescription>
    </briefdescription>
    <detaileddescription>
<para>A <ref refid="class_spicy_pixel_1_1_threading_1_1_fiber" kindref="compound">Fiber</ref> is a lightweight means of scheduling work that enables multiple units of processing to execute concurrently by co-operatively sharing execution time on a single thread. Fibers are also known as &quot;micro-threads&quot; and can be implemented using programming language facilities such as &quot;coroutines&quot;.</para>
<para>Fibers simplify many concurrency issues generally associated with multithreading because a given fiber has complete control over when it yields execution to another fiber. A fiber does not need to manage resource locking or handle changing data in the same way as a thread does because access to a resource is never preempted by another fiber without co-operation.</para>
<para>Fibers can improve performance in certain applications with concurrency requirements. Because many fibers can run on a thread, this can relieve pressure on precious resources in the thread pool and reduce latency.</para>
<para>Additionally, some applications have concurrent, interdependent processes that naturally lend themselves to co-operative scheduling which can result in greater efficiency when the application manages the context switch instead of a pre-emptive scheduler.</para>
<para>Fibers can also be a convenient way to express a state machine. The master fiber implementing the machine can test state conditions, start new fibers for state actions, yield to an action fiber until it completes, and then handle the transition out of the state and into a new state.</para>
<para><heading level="2">Starting a fiber </heading>
</para>
<para>A fiber can be created and started on the default scheduler for the thread as follows.</para>
<para><programlisting filename=".cs"><codeline><highlight class="normal">Fiber.StartNew(()<sp/>=&gt;<sp/>DoTask());</highlight></codeline>
</programlisting></para>
<para>It is also possible to more precisely control startup and scheduler options.</para>
<para><programlisting filename=".cs"><codeline><highlight class="normal">var<sp/>fiber<sp/>=<sp/></highlight><highlight class="keyword">new</highlight><highlight class="normal"><sp/>Fiber(()<sp/>=&gt;<sp/>DoTask());<sp/></highlight><highlight class="comment">//<sp/>create<sp/>the<sp/>fiber</highlight><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal">fiber.Start(myCustomScheduler);<sp/></highlight><highlight class="comment">//<sp/>queue<sp/>for<sp/>execution<sp/>by<sp/>a<sp/>custom<sp/>scheduler</highlight></codeline>
</programlisting> <heading level="2">Using coroutines </heading>
</para>
<para>A coroutine is a function that can yield execution to another function and this allows multiple functions to execute concurrently on the same thread by co-operatively yielding execution time.</para>
<para>Coroutines must return an IEnumerator type and have one or more yield statements that passes a yield instruction back to the fiber scheduler.</para>
<para><programlisting filename=".cs"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>Main()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>Fiber.StartNew(FadeOutCoroutine());</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
<codeline><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal">IEnumerator<sp/>FadeOutCoroutine()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>var<sp/>totalTime<sp/>=<sp/>4f;</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>var<sp/>currentTime<sp/>=<sp/>totalTime;</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">while</highlight><highlight class="normal">(currentTime<sp/>&gt;<sp/>0f)</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>setAlpha(currentTime<sp/>/<sp/>totalTime);<sp/></highlight><highlight class="comment">//<sp/>fade<sp/>out</highlight><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>currentTime<sp/>-=<sp/>Time.deltaTime;</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>yield<sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>FiberInstruction.YieldToAnyFiber;</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
</programlisting></para>
<para><heading level="2">Waiting for completion </heading>
</para>
<para>One fiber can wait for completion of another by yielding the <ref refid="class_spicy_pixel_1_1_threading_1_1_yield_until_complete" kindref="compound">YieldUntilComplete</ref> instruction returned by <ref refid="class_spicy_pixel_1_1_threading_1_1_fiber_1a4d92c296291f4f1f51e7851a70575f34" kindref="member">Start</ref>.</para>
<para><programlisting filename=".cs"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>Main()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>Fiber.StartNew(Fiber1());</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
<codeline><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal">IEnumerator<sp/>Fiber1()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>Console.Out.WriteLine(“Beginning<sp/>Fiber<sp/>1<sp/>and<sp/>waiting<sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal"><sp/>Fiber<sp/>2<sp/>to<sp/>complete”);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>yield<sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>Fiber.StartNew(Fiber2());</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>Console.Out.WriteLine(“Fiber<sp/>2<sp/>has<sp/>completed.);</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
<codeline><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal">IEnumerator<sp/>Fiber2()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="comment">//<sp/>Do<sp/>work</highlight><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">while</highlight><highlight class="normal">(!workDone)</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>Process();</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>yield<sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>FiberInstruction.YieldToAnyFiber;</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
</programlisting></para>
<para><heading level="2">Starting a fiber scheduler </heading>
</para>
<para>Fiber coordination and execution is handled by a <ref refid="class_spicy_pixel_1_1_threading_1_1_fiber_scheduler" kindref="compound">FiberScheduler</ref>. The default system scheduler can be started on the running thread as follows.</para>
<para><programlisting filename=".cs"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>Main()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>FiberScheduler.Current.Run(</highlight><highlight class="keyword">new</highlight><highlight class="normal"><sp/>Fiber(MainFiber()));</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
<codeline><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal">IEnumerator<sp/>MainFiber()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="comment">//<sp/>do<sp/>work</highlight><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
</programlisting></para>
<para><heading level="2">Starting a fiber scheduler on a new thread </heading>
</para>
<para>It is often more convenient to start a fiber scheduler on a new thread. The <ref refid="class_spicy_pixel_1_1_threading_1_1_system_fiber_scheduler" kindref="compound">SystemFiberScheduler</ref> has convenience methods to create the scheduler on a new thread and return a reference.</para>
<para><programlisting filename=".cs"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>Main()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>var<sp/>scheduler<sp/>=<sp/>SystemFiberScheduler.StartNew(</highlight><highlight class="keyword">new</highlight><highlight class="normal"><sp/>Fiber(MainFiber()));</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
<codeline><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal">IEnumerator<sp/>MainFiber()</highlight></codeline>
<codeline><highlight class="normal">{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="comment">//<sp/>do<sp/>work</highlight><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
</programlisting> </para>
    </detaileddescription>
  </compounddef>
</doxygen>
