audit pass introduction and background_information

This commit is contained in:
cfsamson
2020-04-06 12:28:49 +02:00
parent 9b9b72afa5
commit 9c2079c839
17 changed files with 639 additions and 71 deletions

View File

@@ -153,8 +153,8 @@
<p>Before we go into the details about Futures in Rust, let's take a quick look
at the alternatives for handling concurrent programming in general and some
pros and cons for each of them.</p>
<p>While we do that we'll get some information on concurrency which will make it
easier for us when we dive in to Futures specifically.</p>
<p>While we do that we'll also explain some aspects when it comes to concurrency which
will make it easier for us when we dive in to Futures specifically.</p>
<blockquote>
<p>For fun, I've added a small snipped of runnable code with most of the examples.
If you're like me, things get way more interesting then and maybe you'll se some
@@ -210,7 +210,7 @@ fn main() {
</code></pre></pre>
<p>OS threads sure has some pretty big advantages. So why all this talk about
&quot;async&quot; and concurrency in the first place?</p>
<p>First of all. For computers to be <a href="https://en.wikipedia.org/wiki/Efficiency"><em>efficient</em></a> it needs to multitask. Once you
<p>First of all. For computers to be <a href="https://en.wikipedia.org/wiki/Efficiency"><em>efficient</em></a> they needs to multitask. Once you
start to look under the covers (like <a href="https://os.phil-opp.com/async-await/">how an operating system works</a>)
you'll see concurrency everywhere. It's very fundamental in everything we do.</p>
<p>Secondly, we have the web. </p>
@@ -218,10 +218,9 @@ you'll see concurrency everywhere. It's very fundamental in everything we do.</p
(requests). When the number of small tasks is large it's not a good fit for OS
threads as of today because of the memory they require and the overhead involved
when creating new threads. </p>
<p>This gets even more relevant when the load is variable
which means the current number of tasks a program has at any point in time is
unpredictable. That's why you'll see so many async web frameworks and database
drivers today.</p>
<p>This gets even more problematic when the load is variable which means the current number of tasks a
program has at any point in time is unpredictable. That's why you'll see so many async web
frameworks and database drivers today.</p>
<p>However, for a huge number of problems, the standard OS threads will often be the
right solution. So, just think twice about your problem before you reach for an
async library.</p>
@@ -237,15 +236,16 @@ such a system) which then continues running a different task.</p>
<p>Rust had green threads once, but they were removed before it hit 1.0. The state
of execution is stored in each stack so in such a solution there would be no
need for <code>async</code>, <code>await</code>, <code>Futures</code> or <code>Pin</code>. </p>
<p>The typical flow will be like this:</p>
<p><strong>The typical flow looks like this:</strong></p>
<ol>
<li>Run som non-blocking code</li>
<li>Run some non-blocking code</li>
<li>Make a blocking call to some external resource</li>
<li>CPU jumps to the &quot;main&quot; thread which schedules a different thread to run and
&quot;jumps&quot; to that stack</li>
<li>Run some non-blocking code on the new thread until a new blocking call or the
task is finished</li>
<li>&quot;jumps&quot; back to the &quot;main&quot; thread, schedule a new thread to run and jump to that</li>
<li>&quot;jumps&quot; back to the &quot;main&quot; thread, schedule a new thread which is ready to make
progress and jump to that.</li>
</ol>
<p>These &quot;jumps&quot; are know as <strong>context switches</strong>. Your OS is doing it many times each
second as you read this.</p>
@@ -501,16 +501,17 @@ in life, close your eyes now and scroll down for 2-3 seconds. You'll find a link
there that takes you to safety.</p>
</blockquote>
<p>The whole idea behind a callback based approach is to save a pointer to a set of
instructions we want to run later. We can save that pointer on the stack before
we yield control to the runtime, or in some sort of collection as we do below.</p>
<p>The basic idea of not involving threads as a primary way to achieve concurrency
instructions we want to run later together with whatever state is needed. In rust this
would be a <code>closure</code>. In the example below, we save this information in a <code>HashMap</code>
but it's not the only option.</p>
<p>The basic idea of <em>not</em> involving threads as a primary way to achieve concurrency
is the common denominator for the rest of the approaches. Including the one
Rust uses today which we'll soon get to.</p>
<p><strong>Advantages:</strong></p>
<ul>
<li>Easy to implement in most languages</li>
<li>No context switching</li>
<li>Low memory overhead (in most cases)</li>
<li>Relatively low memory overhead (in most cases)</li>
</ul>
<p><strong>Drawbacks:</strong></p>
<ul>
@@ -594,10 +595,10 @@ impl Runtime {
</code></pre></pre>
<p>We're keeping this super simple, and you might wonder what's the difference
between this approach and the one using OS threads an passing in the callbacks
to the OS threads directly. </p>
to the OS threads directly.</p>
<p>The difference is that the callbacks are run on the
same thread using this example. The OS threads we create are basically just used
as timers.</p>
as timers but could represent any kind of resource that we'll have to wait for.</p>
<h2><a class="header" href="#from-callbacks-to-promises" id="from-callbacks-to-promises">From callbacks to promises</a></h2>
<p>You might start to wonder by now, when are we going to talk about Futures?</p>
<p>Well, we're getting there. You see <code>promises</code>, <code>futures</code> and other names for
@@ -652,7 +653,7 @@ Rusts Futures 3.0 is a lot like async/await in our last example.</p>
go through all this is to get an introduction and get into the right mindset for
exploring Rusts Futures.</p>
<blockquote>
<p>To avoid confusion later on: There is one difference you should know. Javascript
<p>To avoid confusion later on: There's one difference you should know. Javascript
promises are <em>eagerly</em> evaluated. That means that once it's created, it starts
running a task. Rusts Futures on the other hand is <em>lazily</em> evaluated. They
need to be polled once before they do any work.</p>