dev-notes/languages/rust/concurrency.html

4976 lines
No EOL
143 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="author" content="Marcello Lamonaca">
<link rel="canonical" href="http://m-lamonaca.github.io/dev-notes/languages/rust/concurrency.html">
<link rel="prev" href="cargo.html">
<link rel="next" href="unit-tests.html">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.34">
<title>Concurrency - Dev Notes</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.35f28582.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.min.css">
<script src="https://unpkg.com/iframe-worker/shim"></script>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<meta property="og:type" content="website" >
<meta property="og:title" content="Concurrency - Dev Notes" >
<meta property="og:description" content="None" >
<meta property="og:image" content="http://m-lamonaca.github.io/dev-notes/assets/images/social/languages/rust/concurrency.png" >
<meta property="og:image:type" content="image/png" >
<meta property="og:image:width" content="1200" >
<meta property="og:image:height" content="630" >
<meta property="og:url" content="http://m-lamonaca.github.io/dev-notes/languages/rust/concurrency.html" >
<meta name="twitter:card" content="summary_large_image" >
<meta name="twitter:title" content="Concurrency - Dev Notes" >
<meta name="twitter:description" content="None" >
<meta name="twitter:image" content="http://m-lamonaca.github.io/dev-notes/assets/images/social/languages/rust/concurrency.png" >
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="orange" data-md-color-accent="deep-orange">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#concurrency" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../../index.html" title="Dev Notes" class="md-header__button md-logo" aria-label="Dev Notes" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M392.8 1.2c-17-4.9-34.7 5-39.6 22l-128 448c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l128-448c4.9-17-5-34.7-22-39.6m80.6 120.1c-12.5 12.5-12.5 32.8 0 45.3l89.3 89.4-89.4 89.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-112-112c-12.5-12.5-32.8-12.5-45.3 0zm-306.7 0c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l112 112c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256l89.4-89.4c12.5-12.5 12.5-32.8 0-45.3"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Dev Notes
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Concurrency
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="orange" data-md-color-accent="deep-orange" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="orange" data-md-color-accent="deep-orange" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/m-lamonaca/dev-notes" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
</nav>
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../../index.html" class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../../containers/docker.html" class="md-tabs__link">
Containers
</a>
</li>
<li class="md-tabs__item">
<a href="../../databases/redis.html" class="md-tabs__link">
Databases
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../html/html.html" class="md-tabs__link">
Languages
</a>
</li>
<li class="md-tabs__item">
<a href="../../misc/git.html" class="md-tabs__link">
Misc
</a>
</li>
<li class="md-tabs__item">
<a href="../../linux/filesystem/file-links.html" class="md-tabs__link">
Linux
</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../../index.html" title="Dev Notes" class="md-nav__button md-logo" aria-label="Dev Notes" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M392.8 1.2c-17-4.9-34.7 5-39.6 22l-128 448c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l128-448c4.9-17-5-34.7-22-39.6m80.6 120.1c-12.5 12.5-12.5 32.8 0 45.3l89.3 89.4-89.4 89.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-112-112c-12.5-12.5-32.8-12.5-45.3 0zm-306.7 0c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l112 112c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256l89.4-89.4c12.5-12.5 12.5-32.8 0-45.3"/></svg>
</a>
Dev Notes
</label>
<div class="md-nav__source">
<a href="https://github.com/m-lamonaca/dev-notes" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../index.html" class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
<span class="md-ellipsis">
Containers
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Containers
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../containers/docker.html" class="md-nav__link">
<span class="md-ellipsis">
Docker
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../containers/kubernetes.html" class="md-nav__link">
<span class="md-ellipsis">
Kubernetes
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Databases
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Databases
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../databases/redis.html" class="md-nav__link">
<span class="md-ellipsis">
Redis
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../databases/sql.html" class="md-nav__link">
<span class="md-ellipsis">
SQL
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../databases/mongo-db.html" class="md-nav__link">
<span class="md-ellipsis">
MongoDB
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" checked>
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="">
<span class="md-ellipsis">
Languages
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Languages
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../html/html.html" class="md-nav__link">
<span class="md-ellipsis">
HTML
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../markdown.html" class="md-nav__link">
<span class="md-ellipsis">
Markdown
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../css/css.html" class="md-nav__link">
<span class="md-ellipsis">
CSS
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../c/c.html" class="md-nav__link">
<span class="md-ellipsis">
C
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../kotlin/kotlin.html" class="md-nav__link">
<span class="md-ellipsis">
Kotlin
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../swift/swift.html" class="md-nav__link">
<span class="md-ellipsis">
Swift
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_7" >
<label class="md-nav__link" for="__nav_4_7" id="__nav_4_7_label" tabindex="">
<span class="md-ellipsis">
Assembly
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_7">
<span class="md-nav__icon md-icon"></span>
Assembly
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../assembly/intel.html" class="md-nav__link">
<span class="md-ellipsis">
Intel
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../assembly/riscv.html" class="md-nav__link">
<span class="md-ellipsis">
RISC-V
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_8" >
<label class="md-nav__link" for="__nav_4_8" id="__nav_4_8_label" tabindex="">
<span class="md-ellipsis">
Python
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_8">
<span class="md-nav__icon md-icon"></span>
Python
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../python/python.html" class="md-nav__link">
<span class="md-ellipsis">
Python
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_8_2" >
<label class="md-nav__link" for="__nav_4_8_2" id="__nav_4_8_2_label" tabindex="0">
<span class="md-ellipsis">
Modules
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_4_8_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_8_2">
<span class="md-nav__icon md-icon"></span>
Modules
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../python/modules/argparse.html" class="md-nav__link">
<span class="md-ellipsis">
argparse
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/collections.html" class="md-nav__link">
<span class="md-ellipsis">
collection
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/csv.html" class="md-nav__link">
<span class="md-ellipsis">
csv
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/ftplib.html" class="md-nav__link">
<span class="md-ellipsis">
ftplib
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/itertools.html" class="md-nav__link">
<span class="md-ellipsis">
itertools
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/json.html" class="md-nav__link">
<span class="md-ellipsis">
json
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/logging.html" class="md-nav__link">
<span class="md-ellipsis">
logging
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/shutil.html" class="md-nav__link">
<span class="md-ellipsis">
shutil
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/smtplib.html" class="md-nav__link">
<span class="md-ellipsis">
smtplib
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/socket.html" class="md-nav__link">
<span class="md-ellipsis">
socket
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/sqlite.html" class="md-nav__link">
<span class="md-ellipsis">
sqlite
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/time-datetime.html" class="md-nav__link">
<span class="md-ellipsis">
time & datetime
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/modules/unittest.html" class="md-nav__link">
<span class="md-ellipsis">
unittest
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_8_3" >
<label class="md-nav__link" for="__nav_4_8_3" id="__nav_4_8_3_label" tabindex="0">
<span class="md-ellipsis">
Libraries
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_4_8_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_8_3">
<span class="md-nav__icon md-icon"></span>
Libraries
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../python/libs/tkinter.html" class="md-nav__link">
<span class="md-ellipsis">
TKinter
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/libs/numpy.html" class="md-nav__link">
<span class="md-ellipsis">
Numpy
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/libs/pandas.html" class="md-nav__link">
<span class="md-ellipsis">
Pandas
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/libs/seaborn.html" class="md-nav__link">
<span class="md-ellipsis">
Seaborn
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/libs/requests.html" class="md-nav__link">
<span class="md-ellipsis">
Requests
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../python/libs/beautiful-soup.html" class="md-nav__link">
<span class="md-ellipsis">
Beatiful Soup
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_9" >
<label class="md-nav__link" for="__nav_4_9" id="__nav_4_9_label" tabindex="">
<span class="md-ellipsis">
.NET
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_9">
<span class="md-nav__icon md-icon"></span>
.NET
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_9_1" >
<label class="md-nav__link" for="__nav_4_9_1" id="__nav_4_9_1_label" tabindex="0">
<span class="md-ellipsis">
C#
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_4_9_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_9_1">
<span class="md-nav__icon md-icon"></span>
C#
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../dotnet/csharp/csharp.html" class="md-nav__link">
<span class="md-ellipsis">
C#
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/csharp/linq.html" class="md-nav__link">
<span class="md-ellipsis">
Linq
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/csharp/collections.html" class="md-nav__link">
<span class="md-ellipsis">
Collections
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/csharp/reactive-extensions.html" class="md-nav__link">
<span class="md-ellipsis">
Reactive Extensions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/csharp/async-programming.html" class="md-nav__link">
<span class="md-ellipsis">
Async Programming
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/csharp/unit-tests.html" class="md-nav__link">
<span class="md-ellipsis">
Unit Tests
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_9_2" >
<label class="md-nav__link" for="__nav_4_9_2" id="__nav_4_9_2_label" tabindex="0">
<span class="md-ellipsis">
ASP.NET
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_4_9_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_9_2">
<span class="md-nav__icon md-icon"></span>
ASP.NET
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../dotnet/asp.net/minimal-api.html" class="md-nav__link">
<span class="md-ellipsis">
Minimal API
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/asp.net/filters.html" class="md-nav__link">
<span class="md-ellipsis">
FIlters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/asp.net/middleware.html" class="md-nav__link">
<span class="md-ellipsis">
Middleware
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/asp.net/razor-syntax.html" class="md-nav__link">
<span class="md-ellipsis">
Razor Syntax
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/asp.net/blazor.html" class="md-nav__link">
<span class="md-ellipsis">
Blazor
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/asp.net/signalr.html" class="md-nav__link">
<span class="md-ellipsis">
SignalR
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/asp.net/web-forms.html" class="md-nav__link">
<span class="md-ellipsis">
Web Forms
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_9_3" >
<label class="md-nav__link" for="__nav_4_9_3" id="__nav_4_9_3_label" tabindex="0">
<span class="md-ellipsis">
Database
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_4_9_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_9_3">
<span class="md-nav__icon md-icon"></span>
Database
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../dotnet/database/ado.net.html" class="md-nav__link">
<span class="md-ellipsis">
ADO.NET
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../dotnet/database/entity-framework.html" class="md-nav__link">
<span class="md-ellipsis">
Entity Framework
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_10" >
<label class="md-nav__link" for="__nav_4_10" id="__nav_4_10_label" tabindex="">
<span class="md-ellipsis">
Java
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_10_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_10">
<span class="md-nav__icon md-icon"></span>
Java
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../java/java.html" class="md-nav__link">
<span class="md-ellipsis">
Java
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../java/java-collection-framework.html" class="md-nav__link">
<span class="md-ellipsis">
Java Collection Framework
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../java/dao.html" class="md-nav__link">
<span class="md-ellipsis">
DAO
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_10_4" >
<label class="md-nav__link" for="__nav_4_10_4" id="__nav_4_10_4_label" tabindex="0">
<span class="md-ellipsis">
Web
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_4_10_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_10_4">
<span class="md-nav__icon md-icon"></span>
Web
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../java/web/servlet.html" class="md-nav__link">
<span class="md-ellipsis">
Serverlet
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_10_4_2" >
<label class="md-nav__link" for="__nav_4_10_4_2" id="__nav_4_10_4_2_label" tabindex="0">
<span class="md-ellipsis">
Spring
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="4" aria-labelledby="__nav_4_10_4_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_10_4_2">
<span class="md-nav__icon md-icon"></span>
Spring
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../java/spring/pom.xml.html" class="md-nav__link">
<span class="md-ellipsis">
POM
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../java/spring/spring-project.html" class="md-nav__link">
<span class="md-ellipsis">
Project Structure
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_11" >
<label class="md-nav__link" for="__nav_4_11" id="__nav_4_11_label" tabindex="">
<span class="md-ellipsis">
PHP
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_11_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_11">
<span class="md-nav__icon md-icon"></span>
PHP
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../php/php.html" class="md-nav__link">
<span class="md-ellipsis">
PHP
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php/database.html" class="md-nav__link">
<span class="md-ellipsis">
Database
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php/web.html" class="md-nav__link">
<span class="md-ellipsis">
Web
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php/dependency-injection.html" class="md-nav__link">
<span class="md-ellipsis">
Dependency Injection
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php/unit-tests.html" class="md-nav__link">
<span class="md-ellipsis">
Unit Tests
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php/composer.html" class="md-nav__link">
<span class="md-ellipsis">
Composer
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php/psr-7.html" class="md-nav__link">
<span class="md-ellipsis">
PSR 7
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php/plates-templating.html" class="md-nav__link">
<span class="md-ellipsis">
Plates
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_11_9" >
<label class="md-nav__link" for="__nav_4_11_9" id="__nav_4_11_9_label" tabindex="0">
<span class="md-ellipsis">
Simple MVC
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_4_11_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_11_9">
<span class="md-nav__icon md-icon"></span>
Simple MVC
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../php/simple-mvc/simple-mvc.html" class="md-nav__link">
<span class="md-ellipsis">
Simple MVC
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../php/simple-mvc/rest-api.html" class="md-nav__link">
<span class="md-ellipsis">
REST API
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_12" checked>
<label class="md-nav__link" for="__nav_4_12" id="__nav_4_12_label" tabindex="">
<span class="md-ellipsis">
Rust
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_12_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_4_12">
<span class="md-nav__icon md-icon"></span>
Rust
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="rust.html" class="md-nav__link">
<span class="md-ellipsis">
Rust
</span>
</a>
</li>
<li class="md-nav__item">
<a href="macros.html" class="md-nav__link">
<span class="md-ellipsis">
Macros
</span>
</a>
</li>
<li class="md-nav__item">
<a href="cargo.html" class="md-nav__link">
<span class="md-ellipsis">
Cargo
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Concurrency
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="concurrency.html" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Concurrency
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#threads" class="md-nav__link">
<span class="md-ellipsis">
Threads
</span>
</a>
<nav class="md-nav" aria-label="Threads">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#scoped-threads" class="md-nav__link">
<span class="md-ellipsis">
Scoped Threads
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#shared-ownership" class="md-nav__link">
<span class="md-ellipsis">
Shared Ownership
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#thread-safety-send-and-sync" class="md-nav__link">
<span class="md-ellipsis">
Thread Safety: Send and Sync
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#locking-protecting-shared-data" class="md-nav__link">
<span class="md-ellipsis">
Locking: Protecting Shared Data
</span>
</a>
<nav class="md-nav" aria-label="Locking: Protecting Shared Data">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mutex" class="md-nav__link">
<span class="md-ellipsis">
Mutex
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#lock-poisoning" class="md-nav__link">
<span class="md-ellipsis">
Lock Poisoning
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reader-writer-lock" class="md-nav__link">
<span class="md-ellipsis">
Reader-Writer Lock
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#waiting-putting-thread-to-sleep" class="md-nav__link">
<span class="md-ellipsis">
Waiting: Putting Thread to Sleep
</span>
</a>
<nav class="md-nav" aria-label="Waiting: Putting Thread to Sleep">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#thread-parking" class="md-nav__link">
<span class="md-ellipsis">
Thread Parking
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#condition-variables" class="md-nav__link">
<span class="md-ellipsis">
Condition Variables
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#atomics" class="md-nav__link">
<span class="md-ellipsis">
Atomics
</span>
</a>
<nav class="md-nav" aria-label="Atomics">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#load-store" class="md-nav__link">
<span class="md-ellipsis">
Load &amp; Store
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#fetch-and-modify-operations" class="md-nav__link">
<span class="md-ellipsis">
Fetch-and-Modify Operations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#compare-and-exchange-operations" class="md-nav__link">
<span class="md-ellipsis">
Compare-and-Exchange Operations
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#memory-ordering" class="md-nav__link">
<span class="md-ellipsis">
Memory Ordering
</span>
</a>
<nav class="md-nav" aria-label="Memory Ordering">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#reordering-and-optimizations" class="md-nav__link">
<span class="md-ellipsis">
Reordering and Optimizations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-memory-model" class="md-nav__link">
<span class="md-ellipsis">
The Memory Model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#happens-before-relationship" class="md-nav__link">
<span class="md-ellipsis">
Happens-Before Relationship
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#relaxed-ordering" class="md-nav__link">
<span class="md-ellipsis">
Relaxed Ordering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#release-and-acquire-ordering" class="md-nav__link">
<span class="md-ellipsis">
Release and Acquire Ordering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#consume-ordering" class="md-nav__link">
<span class="md-ellipsis">
Consume Ordering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sequentially-consistent-ordering" class="md-nav__link">
<span class="md-ellipsis">
Sequentially Consistent Ordering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#fences" class="md-nav__link">
<span class="md-ellipsis">
Fences
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="unit-tests.html" class="md-nav__link">
<span class="md-ellipsis">
Unit Tests
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_13" >
<label class="md-nav__link" for="__nav_4_13" id="__nav_4_13_label" tabindex="">
<span class="md-ellipsis">
Javascript
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_13_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_13">
<span class="md-nav__icon md-icon"></span>
Javascript
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../javascript/javascript.html" class="md-nav__link">
<span class="md-ellipsis">
Javascript
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript/dom.html" class="md-nav__link">
<span class="md-ellipsis">
DOM
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript/events-animation.html" class="md-nav__link">
<span class="md-ellipsis">
Events & Animation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript/ajax.html" class="md-nav__link">
<span class="md-ellipsis">
AJAX
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript/jquery.html" class="md-nav__link">
<span class="md-ellipsis">
jQuery
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_13_6" >
<label class="md-nav__link" for="__nav_4_13_6" id="__nav_4_13_6_label" tabindex="0">
<span class="md-ellipsis">
React
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_4_13_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_13_6">
<span class="md-nav__icon md-icon"></span>
React
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../javascript/react/react.html" class="md-nav__link">
<span class="md-ellipsis">
React
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript/react/react-router.html" class="md-nav__link">
<span class="md-ellipsis">
React Router
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript/react/react-tests.html" class="md-nav__link">
<span class="md-ellipsis">
React Tests
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript/react/redux.html" class="md-nav__link">
<span class="md-ellipsis">
Redux
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../javascript/react/redux-tests.html" class="md-nav__link">
<span class="md-ellipsis">
Redux Tests
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../javascript/svelte/svelte.html" class="md-nav__link">
<span class="md-ellipsis">
Svelte
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_14" >
<label class="md-nav__link" for="__nav_4_14" id="__nav_4_14_label" tabindex="">
<span class="md-ellipsis">
PowerShell
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_14_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_14">
<span class="md-nav__icon md-icon"></span>
PowerShell
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../powershell/scripting.html" class="md-nav__link">
<span class="md-ellipsis">
Scripting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../powershell/commands.html" class="md-nav__link">
<span class="md-ellipsis">
Commands
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4_15" >
<label class="md-nav__link" for="__nav_4_15" id="__nav_4_15_label" tabindex="">
<span class="md-ellipsis">
Bash
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_4_15_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4_15">
<span class="md-nav__icon md-icon"></span>
Bash
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../bash/scripting.html" class="md-nav__link">
<span class="md-ellipsis">
Scripting
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../bash/commands.html" class="md-nav__link">
<span class="md-ellipsis">
Commands
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Misc
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Misc
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../misc/git.html" class="md-nav__link">
<span class="md-ellipsis">
Git
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../misc/graph-ql.html" class="md-nav__link">
<span class="md-ellipsis">
GraphQL
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../misc/regular-expressions.html" class="md-nav__link">
<span class="md-ellipsis">
RegEx
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../misc/ssh.html" class="md-nav__link">
<span class="md-ellipsis">
SSH
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../misc/web-components.html" class="md-nav__link">
<span class="md-ellipsis">
WebComponents
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
Linux
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Linux
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6_1" >
<label class="md-nav__link" for="__nav_6_1" id="__nav_6_1_label" tabindex="0">
<span class="md-ellipsis">
Filesystem
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_6_1_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6_1">
<span class="md-nav__icon md-icon"></span>
Filesystem
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../linux/filesystem/file-links.html" class="md-nav__link">
<span class="md-ellipsis">
File Links
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../linux/filesystem/procfs.html" class="md-nav__link">
<span class="md-ellipsis">
/proc
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../linux/filesystem/sysfs.html" class="md-nav__link">
<span class="md-ellipsis">
/sys
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6_2" >
<label class="md-nav__link" for="__nav_6_2" id="__nav_6_2_label" tabindex="0">
<span class="md-ellipsis">
System Init
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_6_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6_2">
<span class="md-nav__icon md-icon"></span>
System Init
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../linux/init/systemd.html" class="md-nav__link">
<span class="md-ellipsis">
Systemd
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../linux/init/open-rc.html" class="md-nav__link">
<span class="md-ellipsis">
OpenRC
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#threads" class="md-nav__link">
<span class="md-ellipsis">
Threads
</span>
</a>
<nav class="md-nav" aria-label="Threads">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#scoped-threads" class="md-nav__link">
<span class="md-ellipsis">
Scoped Threads
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#shared-ownership" class="md-nav__link">
<span class="md-ellipsis">
Shared Ownership
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#thread-safety-send-and-sync" class="md-nav__link">
<span class="md-ellipsis">
Thread Safety: Send and Sync
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#locking-protecting-shared-data" class="md-nav__link">
<span class="md-ellipsis">
Locking: Protecting Shared Data
</span>
</a>
<nav class="md-nav" aria-label="Locking: Protecting Shared Data">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mutex" class="md-nav__link">
<span class="md-ellipsis">
Mutex
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#lock-poisoning" class="md-nav__link">
<span class="md-ellipsis">
Lock Poisoning
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reader-writer-lock" class="md-nav__link">
<span class="md-ellipsis">
Reader-Writer Lock
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#waiting-putting-thread-to-sleep" class="md-nav__link">
<span class="md-ellipsis">
Waiting: Putting Thread to Sleep
</span>
</a>
<nav class="md-nav" aria-label="Waiting: Putting Thread to Sleep">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#thread-parking" class="md-nav__link">
<span class="md-ellipsis">
Thread Parking
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#condition-variables" class="md-nav__link">
<span class="md-ellipsis">
Condition Variables
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#atomics" class="md-nav__link">
<span class="md-ellipsis">
Atomics
</span>
</a>
<nav class="md-nav" aria-label="Atomics">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#load-store" class="md-nav__link">
<span class="md-ellipsis">
Load &amp; Store
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#fetch-and-modify-operations" class="md-nav__link">
<span class="md-ellipsis">
Fetch-and-Modify Operations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#compare-and-exchange-operations" class="md-nav__link">
<span class="md-ellipsis">
Compare-and-Exchange Operations
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#memory-ordering" class="md-nav__link">
<span class="md-ellipsis">
Memory Ordering
</span>
</a>
<nav class="md-nav" aria-label="Memory Ordering">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#reordering-and-optimizations" class="md-nav__link">
<span class="md-ellipsis">
Reordering and Optimizations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-memory-model" class="md-nav__link">
<span class="md-ellipsis">
The Memory Model
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#happens-before-relationship" class="md-nav__link">
<span class="md-ellipsis">
Happens-Before Relationship
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#relaxed-ordering" class="md-nav__link">
<span class="md-ellipsis">
Relaxed Ordering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#release-and-acquire-ordering" class="md-nav__link">
<span class="md-ellipsis">
Release and Acquire Ordering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#consume-ordering" class="md-nav__link">
<span class="md-ellipsis">
Consume Ordering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sequentially-consistent-ordering" class="md-nav__link">
<span class="md-ellipsis">
Sequentially Consistent Ordering
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#fences" class="md-nav__link">
<span class="md-ellipsis">
Fences
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="concurrency">Concurrency</h1>
<p><a href="https://doc.rust-lang.org/book/ch16-00-concurrency.html" title="Rust Book - Fearless Concurrency">Rust Book - Concurrency</a><br />
<a href="https://marabos.nl/atomics/" title="Rust Atomics and Locks - Low-Level Concurrency in Practice">Rust Atomics and Locks - Mara Bos</a></p>
<p>Operating systems isolate processes from each other as much as possible, allowing a program to do its thing while completely unaware of what any other processes are doing. For example, a process cannot normally access the memory of another process, or communicate with it in any way, without asking the operating systems kernel first.</p>
<p>However, a program can spawn extra threads of execution, as part of the same process. Threads within the same process are not isolated from each other. Threads share memory and can interact with each other through that memory.</p>
<h2 id="threads">Threads</h2>
<p>Every program starts with exactly <em>one</em> thread: the <strong>main</strong> thread. This thread will execute the <code>main</code> function and can be used to spawn more threads if necessary.</p>
<p>New threads are spawned using the <code>std::thread::spawn</code> function from the standard library. It takes a single argument: the function the new thread will execute. The thread stops once this function returns.</p>
<p>Returning from <code>main</code> will exit the entire program, even if other threads are still running. To make sure the spawned threads have finished their work it's possible to wait by <em>joining</em> them.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span>
<span class="normal"><a href="#__codelineno-0-2">2</a></span>
<span class="normal"><a href="#__codelineno-0-3">3</a></span>
<span class="normal"><a href="#__codelineno-0-4">4</a></span>
<span class="normal"><a href="#__codelineno-0-5">5</a></span>
<span class="normal"><a href="#__codelineno-0-6">6</a></span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span>
<span class="normal"><a href="#__codelineno-0-8">8</a></span>
<span class="normal"><a href="#__codelineno-0-9">9</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="c1">// spawn a new thread</span>
<a id="__codelineno-0-2" name="__codelineno-0-2"></a><span class="kd">let</span><span class="w"> </span><span class="n">handle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">::</span><span class="n">thread</span><span class="p">::</span><span class="n">spawn</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-0-3" name="__codelineno-0-3"></a>
<a id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="w"> </span><span class="c1">// read the current thread ID</span>
<a id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">thread_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">::</span><span class="n">thread</span><span class="p">::</span><span class="n">current</span><span class="p">().</span><span class="n">id</span><span class="p">();</span>
<a id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="p">});</span>
<a id="__codelineno-0-7" name="__codelineno-0-7"></a>
<a id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="c1">// wait for the thread to finish by joining it</span>
<a id="__codelineno-0-9" name="__codelineno-0-9"></a><span class="n">handle</span><span class="p">.</span><span class="n">join</span><span class="p">();</span>
</code></pre></div></td></tr></table></div>
<p>Since a thread might run until the very end of the programs execution, the spawn function has a <code>'static</code> lifetime bound on its argument type. In other words, it only accepts functions that may be kept around forever. A closure capturing a local variable by reference may not be kept around forever, since that reference would become invalid the moment the local variable ceases to exist.</p>
<p>Getting a value back out of the thread is done by returning it from the closure. This return value can be obtained from the <code>Result</code> returned by the <code>join</code> method.</p>
<blockquote>
<p><strong>Note</strong>: if a thread panics the handle will return the panic message so that it can be handled.</p>
</blockquote>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-1-1"> 1</a></span>
<span class="normal"><a href="#__codelineno-1-2"> 2</a></span>
<span class="normal"><a href="#__codelineno-1-3"> 3</a></span>
<span class="normal"><a href="#__codelineno-1-4"> 4</a></span>
<span class="normal"><a href="#__codelineno-1-5"> 5</a></span>
<span class="normal"><a href="#__codelineno-1-6"> 6</a></span>
<span class="normal"><a href="#__codelineno-1-7"> 7</a></span>
<span class="normal"><a href="#__codelineno-1-8"> 8</a></span>
<span class="normal"><a href="#__codelineno-1-9"> 9</a></span>
<span class="normal"><a href="#__codelineno-1-10">10</a></span>
<span class="normal"><a href="#__codelineno-1-11">11</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="kd">let</span><span class="w"> </span><span class="n">numbers</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Vec</span><span class="p">::</span><span class="n">from_iter</span><span class="p">(</span><span class="mi">0</span><span class="o">..=</span><span class="mi">1000</span><span class="p">);</span>
<a id="__codelineno-1-2" name="__codelineno-1-2"></a>
<a id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="c1">// `move` ensures the tread takes ownership by move the data</span>
<a id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="kd">let</span><span class="w"> </span><span class="n">handle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">thread</span><span class="p">::</span><span class="n">spawn</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-5" name="__codelineno-1-5"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">numbers</span><span class="p">.</span><span class="n">len</span><span class="p">();</span>
<a id="__codelineno-1-6" name="__codelineno-1-6"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">sum</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">numbers</span><span class="p">.</span><span class="n">iter</span><span class="p">().</span><span class="n">sum</span><span class="p">::</span><span class="o">&lt;</span><span class="kt">usize</span><span class="o">&gt;</span><span class="p">();</span>
<a id="__codelineno-1-7" name="__codelineno-1-7"></a><span class="w"> </span><span class="n">sum</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">len</span>
<a id="__codelineno-1-8" name="__codelineno-1-8"></a><span class="p">});</span>
<a id="__codelineno-1-9" name="__codelineno-1-9"></a>
<a id="__codelineno-1-10" name="__codelineno-1-10"></a>
<a id="__codelineno-1-11" name="__codelineno-1-11"></a><span class="kd">let</span><span class="w"> </span><span class="n">average</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">handle</span><span class="p">.</span><span class="n">join</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span>
</code></pre></div></td></tr></table></div>
<h3 id="scoped-threads">Scoped Threads</h3>
<p><strong>Scoped threads</strong> ensure that all thread spawned within a <em>scope</em> do not outlive said scope. This makes possible to borrow data that outlives the scope. This is possible since the scope <code>spawn</code> function does not have a <code>'static</code> bound.</p>
<p><strong>Note</strong>: it's not possible to spawn multiple threads sharing the same data is one of the is mutating it.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-2-1"> 1</a></span>
<span class="normal"><a href="#__codelineno-2-2"> 2</a></span>
<span class="normal"><a href="#__codelineno-2-3"> 3</a></span>
<span class="normal"><a href="#__codelineno-2-4"> 4</a></span>
<span class="normal"><a href="#__codelineno-2-5"> 5</a></span>
<span class="normal"><a href="#__codelineno-2-6"> 6</a></span>
<span class="normal"><a href="#__codelineno-2-7"> 7</a></span>
<span class="normal"><a href="#__codelineno-2-8"> 8</a></span>
<span class="normal"><a href="#__codelineno-2-9"> 9</a></span>
<span class="normal"><a href="#__codelineno-2-10">10</a></span>
<span class="normal"><a href="#__codelineno-2-11">11</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1"></a><span class="kd">let</span><span class="w"> </span><span class="n">numbers</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Vec</span><span class="p">::</span><span class="n">from_iter</span><span class="p">(</span><span class="mi">0</span><span class="o">..=</span><span class="mi">10</span><span class="p">);</span>
<a id="__codelineno-2-2" name="__codelineno-2-2"></a>
<a id="__codelineno-2-3" name="__codelineno-2-3"></a><span class="n">std</span><span class="p">::</span><span class="n">thread</span><span class="p">::</span><span class="n">scope</span><span class="p">(</span><span class="o">|</span><span class="n">scope</span><span class="o">|</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-4" name="__codelineno-2-4"></a><span class="w"> </span><span class="c1">// data is borrowed since the `move` keyword is missing</span>
<a id="__codelineno-2-5" name="__codelineno-2-5"></a><span class="w"> </span><span class="n">scope</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span>
<a id="__codelineno-2-6" name="__codelineno-2-6"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">numbers</span><span class="p">.</span><span class="n">len</span><span class="p">();</span><span class="w"> </span>
<a id="__codelineno-2-7" name="__codelineno-2-7"></a><span class="w"> </span><span class="c1">// ...</span>
<a id="__codelineno-2-8" name="__codelineno-2-8"></a><span class="w"> </span><span class="p">});</span>
<a id="__codelineno-2-9" name="__codelineno-2-9"></a>
<a id="__codelineno-2-10" name="__codelineno-2-10"></a><span class="w"> </span><span class="n">scope</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* ... */</span><span class="w"> </span><span class="p">});</span>
<a id="__codelineno-2-11" name="__codelineno-2-11"></a><span class="p">});</span>
</code></pre></div></td></tr></table></div>
<h3 id="shared-ownership">Shared Ownership</h3>
<p>When sharing data between two threads where neither thread is guaranteed to outlive the other, neither of them can be the owner of that data. Any data shared between them will need to live as long as the longest living thread.</p>
<p>There are several ways to create data that is not owned by any single thread:</p>
<ul>
<li>
<p><strong>Statics</strong>: A <code>static</code> item has a constant initializer, is never dropped, and already exists before the main function of the program even starts. Every thread can borrow it, since its guaranteed to always exist.</p>
</li>
<li>
<p><strong>Leaking</strong>: Using <code>Box::leak</code>, one can <em>release</em> ownership of a <code>Box</code>, promising to never drop it. From that point on, the <code>Box</code> will live forever, without an owner, allowing it to be borrowed by any thread for as long as the program runs.</p>
</li>
<li>
<p><strong>Reference Counting</strong>: To make sure that shared data gets dropped and deallocated data ownership it's never gave up completely, is instead <em>shared</em>. By keeping track of the number of owners, it's possible to make sure the value is dropped only when there are no owners left. The standard library offers such functionality with the <code>Rc&lt;T&gt;</code> &amp; <code>Arc&lt;T&gt;</code> types.</p>
</li>
</ul>
<h3 id="thread-safety-send-and-sync">Thread Safety: Send and Sync</h3>
<p>The <code>Send</code> marker trait indicates that ownership of values of the type implementing <code>Send</code> can be transferred between threads. Any type composed entirely of <code>Send</code> types is automatically marked as <code>Send</code>. Almost all primitive types are <code>Send</code>, aside from raw pointers.</p>
<p>The <code>Sync</code> marker trait indicates that it is safe for the type implementing <code>Sync</code> to be referenced from multiple threads. In other words, any type <code>T</code> is <code>Sync</code> if <code>&amp;T</code> (an immutable reference to <code>T</code>) is <code>Send</code>, meaning the reference can be sent safely to another thread. Similar to <code>Send</code>, primitive types are <code>Sync</code>, and types composed entirely of types that are <code>Sync</code>are also <code>Sync</code>.</p>
<blockquote>
<p><strong>Note</strong>: All primitive types such as <code>i32</code>, <code>bool</code>, and <code>str</code> are both <code>Send</code> and <code>Sync</code>.</p>
</blockquote>
<h2 id="locking-protecting-shared-data">Locking: Protecting Shared Data</h2>
<h3 id="mutex">Mutex</h3>
<p>The most commonly used tool for sharing (mutable) data between threads is a <strong>mutex</strong>, which is short for "mutual exclusion." The job of a mutex is to ensure threads have <em>exclusive access</em> to some data by temporarily blocking other threads that try to access it at the same time.</p>
<p>A mutex has only two <em>states</em>: <strong>locked</strong> and <strong>unlocked</strong>.</p>
<p>When a thread locks an unlocked mutex, the mutex is marked as locked and the thread can immediately continue. When a thread then attempts to lock an already locked mutex, that operation will block. The thread is put to sleep while it waits for the mutex to be unlocked. Unlocking is only possible on a locked mutex, and should be done by the same thread that locked it. If other threads are waiting to lock the mutex, unlocking will cause one of those threads to be woken up, so it can try to lock the mutex again and continue its course.</p>
<p>Protecting data with a mutex is simply the agreement between all threads that they will only access the data when they have the mutex locked. That way, no two threads can ever access that data concurrently and cause a <strong>data race</strong>.</p>
<p>The Rust standard library provides this functionality through <code>std::sync::Mutex&lt;T&gt;</code>. Since the mutex wraps and owns the <code>T</code> it protects, the data can only be accessed through the mutex, allowing for a safe interface that can guarantee only one thread at a time can access the wrapped <code>T</code>.</p>
<p>To ensure a locked mutex can only be unlocked by the thread that locked it, it does not have an <code>unlock()</code> method. Instead, its <code>lock()</code> method returns a a <code>MutexGuard</code> to represent the lock. The <code>MutexGuard</code> allows exclusive access to the data the mutex protects. Unlocking the mutex is done by dropping the guard.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-3-1">1</a></span>
<span class="normal"><a href="#__codelineno-3-2">2</a></span>
<span class="normal"><a href="#__codelineno-3-3">3</a></span>
<span class="normal"><a href="#__codelineno-3-4">4</a></span>
<span class="normal"><a href="#__codelineno-3-5">5</a></span>
<span class="normal"><a href="#__codelineno-3-6">6</a></span>
<span class="normal"><a href="#__codelineno-3-7">7</a></span>
<span class="normal"><a href="#__codelineno-3-8">8</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1"></a><span class="kd">let</span><span class="w"> </span><span class="n">mutex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">::</span><span class="n">sync</span><span class="p">::</span><span class="n">Mutex</span><span class="p">::</span><span class="n">new</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<a id="__codelineno-3-2" name="__codelineno-3-2"></a>
<a id="__codelineno-3-3" name="__codelineno-3-3"></a><span class="n">std</span><span class="p">::</span><span class="n">thread</span><span class="p">::</span><span class="n">scope</span><span class="p">(</span><span class="o">|</span><span class="n">scope</span><span class="o">|</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-4" name="__codelineno-3-4"></a><span class="w"> </span><span class="n">scope</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-5" name="__codelineno-3-5"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">guard</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mutex</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w"> </span><span class="c1">// obtain access</span>
<a id="__codelineno-3-6" name="__codelineno-3-6"></a><span class="w"> </span><span class="o">*</span><span class="n">guard</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// mutate protected value</span>
<a id="__codelineno-3-7" name="__codelineno-3-7"></a><span class="w"> </span><span class="p">})</span>
<a id="__codelineno-3-8" name="__codelineno-3-8"></a><span class="p">});</span>
</code></pre></div></td></tr></table></div>
<h3 id="lock-poisoning">Lock Poisoning</h3>
<p>The <code>lock()</code> method returns a <code>Result</code> since the mutex can become <strong>poisoned</strong>. A mutex get marked as poisoned when a thread panics while holding the lock. Calling <code>lock()</code> on a poisoned mutex will return an <code>Err</code>. This poisoning mechanism protects against accessing data that may be in an inconsistent state. </p>
<blockquote>
<p><strong>Note</strong>: The lock is still acquired and the <code>Err</code> variant contains the guard, allowing to correct the data inconsistency.</p>
</blockquote>
<h3 id="reader-writer-lock">Reader-Writer Lock</h3>
<p>A <strong>reader-writer lock</strong> understands the difference between <em>exclusive</em> and <em>shared</em> access, and can provide either. It has three states: unlocked, locked by a single writer (for exclusive access), and locked by any number of readers (for shared access).</p>
<p>The Rust standard library provides this lock through the <code>std::sync::RwLock&lt;T&gt;</code> type. It has a <code>read()</code> and <code>write()</code> method for locking as either a reader or a writer and it has two guard types: <code>RwLockReadGuard</code> and <code>RwLockWriteGuard</code>.</p>
<p>The first only implements <code>Deref</code> to behave like a shared reference to the protected data, while the second also implements <code>DerefMut</code> to behave like an exclusive reference.</p>
<p>Most implementations will block new readers when there is a writer waiting, even when the lock is already read-locked. This is done to prevent <em>writer starvation</em>, a situation where many readers collectively keep the lock from ever unlocking, never allowing any writer to update the data.</p>
<h2 id="waiting-putting-thread-to-sleep">Waiting: Putting Thread to Sleep</h2>
<h3 id="thread-parking">Thread Parking</h3>
<p>One way to wait for a notification from another thread is called thread <strong>parking</strong>. A thread can <em>park</em> itself, which puts it to sleep, stopping it from consuming any CPU cycles. Another thread can then <em>unpark</em> the parked thread, waking it up from its sleep.</p>
<p>Thread parking is available through the <code>std::thread::park()</code> function. For unparking, it's possible to call the <code>unpark()</code> method on a <code>Thread</code> handle.</p>
<p>An important property of thread parking is that a call to <code>unpark()</code> before the thread parks itself does not get lost. The request to unpark is still recorded, and the next time the thread tries to park itself, it clears that request and directly continues without actually going to sleep.</p>
<blockquote>
<p><strong>Note</strong>: calls to <code>unpark()</code> do not stack up.</p>
</blockquote>
<h3 id="condition-variables">Condition Variables</h3>
<p><strong>Condition variables</strong> are a more commonly used option for waiting for something to happen to data protected by a mutex. They have two basic operations: <strong>wait</strong> and <strong>notify</strong>.</p>
<p>Threads can wait on a condition variable, after which they can be woken up when another thread notifies that same condition variable. Multiple threads can wait on the same condition variable, and notifications can either be sent to one waiting thread, or to all of them.</p>
<p>To avoid the issue of missing notifications in the brief moment between unlocking a mutex and waiting for a condition variable, condition variables provide a way to atomically unlock the mutex and start waiting. This means there is simply no possible moment for notifications to get lost.</p>
<p>The Rust standard library provides a condition variable as <code>std::sync::Condvar</code>. Its <code>wait</code> method takes a <code>MutexGuard</code> that proves weve locked the mutex. It first unlocks the mutex (allowing other threads to work on it) and goes to sleep. When woken up, it relocks the mutex and returns a new <code>MutexGuard</code> (which proves that the mutex is locked again).</p>
<p>It has two notify functions: <code>notify_one</code> to wake up just one waiting thread (if any), and <code>notify_all</code> to wake them all up.</p>
<h2 id="atomics">Atomics</h2>
<p>The word atomic comes from the Greek word ἄτομος, meaning indivisible, something that cannot be cut into smaller pieces. In computer science, it is used to describe an operation that is indivisible: it is either fully completed, or it didnt happen yet.</p>
<p><strong>Atomic operations</strong> are the main building block for anything involving multiple threads. All the other concurrency primitives, such as mutexes and condition variables, are implemented using atomic operations.</p>
<p>Each of the available atomic types has the same interface with methods for <em>storing</em> and <em>loading</em>, methods for atomic "fetch-and-modify" operations, and some more advanced "compare-and-exchange" methods.</p>
<p>Every atomic operation takes an argument of type <code>std::sync::atomic::Ordering</code>, which determines the guarantees about the relative ordering of operations. Based on the ordering the various threads can witness the same operations happening in different orders.</p>
<h3 id="load-store">Load &amp; Store</h3>
<p>The first two atomic operations are the most basic ones: <strong>load</strong> and <strong>store</strong>. Their function signatures are as follows, using AtomicI32 as an example:</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-4-1">1</a></span>
<span class="normal"><a href="#__codelineno-4-2">2</a></span>
<span class="normal"><a href="#__codelineno-4-3">3</a></span>
<span class="normal"><a href="#__codelineno-4-4">4</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1"></a><span class="k">impl</span><span class="w"> </span><span class="n">AtomicI32</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-2" name="__codelineno-4-2"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">load</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-4-3" name="__codelineno-4-3"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">store</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">value</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">);</span>
<a id="__codelineno-4-4" name="__codelineno-4-4"></a><span class="p">}</span>
</code></pre></div></td></tr></table></div>
<p>The <code>load</code> method atomically loads the value stored in the atomic variable, and the <code>store</code> method atomically stores a new value in it.</p>
<blockquote>
<p><strong>Note</strong>: the store method takes a shared reference (<code>&amp;T</code>) even though it modifies itself.</p>
</blockquote>
<h3 id="fetch-and-modify-operations">Fetch-and-Modify Operations</h3>
<p>The <strong>fetch-and-modify</strong> operations modify the atomic variable, but also load (fetch) the original value, as a single atomic operation.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-5-1"> 1</a></span>
<span class="normal"><a href="#__codelineno-5-2"> 2</a></span>
<span class="normal"><a href="#__codelineno-5-3"> 3</a></span>
<span class="normal"><a href="#__codelineno-5-4"> 4</a></span>
<span class="normal"><a href="#__codelineno-5-5"> 5</a></span>
<span class="normal"><a href="#__codelineno-5-6"> 6</a></span>
<span class="normal"><a href="#__codelineno-5-7"> 7</a></span>
<span class="normal"><a href="#__codelineno-5-8"> 8</a></span>
<span class="normal"><a href="#__codelineno-5-9"> 9</a></span>
<span class="normal"><a href="#__codelineno-5-10">10</a></span>
<span class="normal"><a href="#__codelineno-5-11">11</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1"></a><span class="k">impl</span><span class="w"> </span><span class="n">AtomicI32</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-5-2" name="__codelineno-5-2"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">fetch_add</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-5-3" name="__codelineno-5-3"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">fetch_sub</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-5-4" name="__codelineno-5-4"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">fetch_or</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-5-5" name="__codelineno-5-5"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">fetch_and</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-5-6" name="__codelineno-5-6"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">fetch_nand</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-5-7" name="__codelineno-5-7"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">fetch_xor</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-5-8" name="__codelineno-5-8"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">fetch_max</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-5-9" name="__codelineno-5-9"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">fetch_min</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-5-10" name="__codelineno-5-10"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">swap</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">v</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">ordering</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span><span class="w"> </span><span class="c1">// aka fetch_store</span>
<a id="__codelineno-5-11" name="__codelineno-5-11"></a><span class="p">}</span>
</code></pre></div></td></tr></table></div>
<h3 id="compare-and-exchange-operations">Compare-and-Exchange Operations</h3>
<p>The <strong>compare-and-exchange</strong> operation checks if the atomic value is equal to a given value, and only if that is the case does it replace it with a new value, all atomically as a single operation. It will return the previous value and tell whether it replaced it or not.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-6-1">1</a></span>
<span class="normal"><a href="#__codelineno-6-2">2</a></span>
<span class="normal"><a href="#__codelineno-6-3">3</a></span>
<span class="normal"><a href="#__codelineno-6-4">4</a></span>
<span class="normal"><a href="#__codelineno-6-5">5</a></span>
<span class="normal"><a href="#__codelineno-6-6">6</a></span>
<span class="normal"><a href="#__codelineno-6-7">7</a></span>
<span class="normal"><a href="#__codelineno-6-8">8</a></span>
<span class="normal"><a href="#__codelineno-6-9">9</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1"></a><span class="k">impl</span><span class="w"> </span><span class="n">AtomicI32</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-2" name="__codelineno-6-2"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="nf">compare_exchange</span><span class="p">(</span>
<a id="__codelineno-6-3" name="__codelineno-6-3"></a><span class="w"> </span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span>
<a id="__codelineno-6-4" name="__codelineno-6-4"></a><span class="w"> </span><span class="n">expected</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span>
<a id="__codelineno-6-5" name="__codelineno-6-5"></a><span class="w"> </span><span class="n">new</span><span class="p">:</span><span class="w"> </span><span class="kt">i32</span><span class="p">,</span>
<a id="__codelineno-6-6" name="__codelineno-6-6"></a><span class="w"> </span><span class="n">success_order</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span><span class="p">,</span>
<a id="__codelineno-6-7" name="__codelineno-6-7"></a><span class="w"> </span><span class="n">failure_order</span><span class="p">:</span><span class="w"> </span><span class="nc">Ordering</span>
<a id="__codelineno-6-8" name="__codelineno-6-8"></a><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">-&gt;</span><span class="w"> </span><span class="nb">Result</span><span class="o">&lt;</span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="kt">i32</span><span class="o">&gt;</span><span class="p">;</span>
<a id="__codelineno-6-9" name="__codelineno-6-9"></a><span class="p">}</span>
</code></pre></div></td></tr></table></div>
<h2 id="memory-ordering">Memory Ordering</h2>
<h3 id="reordering-and-optimizations">Reordering and Optimizations</h3>
<p>Processors and compilers perform tricks to make programs run as fast as possible. A processor might determine that two particular consecutive instructions in the program will not affect each other, and execute them out of order, if that is faster.
Similarly, a compiler might decide to reorder or rewrite parts of the program if it has reason to believe it might result in faster execution. But only if that wouldnt change the behavior of the program.</p>
<p>The logic for verifying that a specific reordering or other optimization wont affect the behavior of the program does not take other threads into account. This is why explicitly telling the compiler and processor what they can and cant do with the atomic operations it's necessary, since their usual logic ignores interactions between threads and might allow for optimizations that do change the result of the program.</p>
<p>The available orderings in Rust are:</p>
<ul>
<li>Relaxed ordering: <code>Ordering::Relaxed</code></li>
<li>Release and acquire ordering: <code>Ordering::{Release, Acquire, AcqRel}</code></li>
<li>Sequentially consistent ordering: <code>Ordering::SeqCst</code></li>
</ul>
<h3 id="the-memory-model">The Memory Model</h3>
<p>The different memory ordering options have a strict formal definition to make sure their assumption are known, and compiler writers know exactly what guarantees they need to provide. To decouple this from the details of specific processor architectures, memory ordering is defined in terms of an <em>abstract</em> memory model.</p>
<p>Rusts memory model allows for concurrent atomic stores, but considers concurrent non-atomic stores to the same variable to be a data race, resulting in undefined behavior.</p>
<h3 id="happens-before-relationship">Happens-Before Relationship</h3>
<p>The memory model defines the order in which operations happen in terms of <em>happens-before</em> relationships. This means that as an abstract model only defines situations where one thing is guaranteed to happen before another thing, and leaves the order of everything else undefined.</p>
<p>Between threads, however, happens-before relationships only occur in a few specific cases, such as when spawning and joining a thread, unlocking and locking a mutex, and through atomic operations that use non-relaxed memory ordering. Relaxed memory ordering is the most basic (and most performant) memory ordering that, by itself, never results in any cross-thread happens-before relationships.</p>
<p><em>Spawning</em> a thread creates a happens-before relationship between what happened before the <code>spawn()</code> call, and the new thread. Similarly, <em>joining</em> a thread creates a happens-before relationship between the joined thread and what happens after the <code>join()</code> call.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-7-1"> 1</a></span>
<span class="normal"><a href="#__codelineno-7-2"> 2</a></span>
<span class="normal"><a href="#__codelineno-7-3"> 3</a></span>
<span class="normal"><a href="#__codelineno-7-4"> 4</a></span>
<span class="normal"><a href="#__codelineno-7-5"> 5</a></span>
<span class="normal"><a href="#__codelineno-7-6"> 6</a></span>
<span class="normal"><a href="#__codelineno-7-7"> 7</a></span>
<span class="normal"><a href="#__codelineno-7-8"> 8</a></span>
<span class="normal"><a href="#__codelineno-7-9"> 9</a></span>
<span class="normal"><a href="#__codelineno-7-10">10</a></span>
<span class="normal"><a href="#__codelineno-7-11">11</a></span>
<span class="normal"><a href="#__codelineno-7-12">12</a></span>
<span class="normal"><a href="#__codelineno-7-13">13</a></span>
<span class="normal"><a href="#__codelineno-7-14">14</a></span>
<span class="normal"><a href="#__codelineno-7-15">15</a></span>
<span class="normal"><a href="#__codelineno-7-16">16</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1"></a><span class="k">static</span><span class="w"> </span><span class="n">X</span><span class="p">:</span><span class="w"> </span><span class="nc">AtomicI32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AtomicI32</span><span class="p">::</span><span class="n">new</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<a id="__codelineno-7-2" name="__codelineno-7-2"></a>
<a id="__codelineno-7-3" name="__codelineno-7-3"></a><span class="k">fn</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-4" name="__codelineno-7-4"></a><span class="w"> </span><span class="n">X</span><span class="p">.</span><span class="n">store</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">Relaxed</span><span class="p">);</span>
<a id="__codelineno-7-5" name="__codelineno-7-5"></a>
<a id="__codelineno-7-6" name="__codelineno-7-6"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">thread</span><span class="p">::</span><span class="n">spawn</span><span class="p">(</span><span class="n">f</span><span class="p">);</span><span class="w"> </span><span class="c1">// happens after &quot;store 1&quot;</span>
<a id="__codelineno-7-7" name="__codelineno-7-7"></a><span class="w"> </span><span class="n">X</span><span class="p">.</span><span class="n">store</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">Relaxed</span><span class="p">);</span>
<a id="__codelineno-7-8" name="__codelineno-7-8"></a><span class="w"> </span><span class="n">t</span><span class="p">.</span><span class="n">join</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w"> </span><span class="c1">// happens before &quot;store 3&quot;</span>
<a id="__codelineno-7-9" name="__codelineno-7-9"></a>
<a id="__codelineno-7-10" name="__codelineno-7-10"></a><span class="w"> </span><span class="n">X</span><span class="p">.</span><span class="n">store</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="n">Relaxed</span><span class="p">);</span>
<a id="__codelineno-7-11" name="__codelineno-7-11"></a><span class="p">}</span>
<a id="__codelineno-7-12" name="__codelineno-7-12"></a>
<a id="__codelineno-7-13" name="__codelineno-7-13"></a><span class="k">fn</span><span class="w"> </span><span class="nf">f</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-14" name="__codelineno-7-14"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">X</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">Relaxed</span><span class="p">);</span><span class="w"> </span><span class="c1">// could happen after either before or after &quot;store 2&quot;</span>
<a id="__codelineno-7-15" name="__codelineno-7-15"></a><span class="w"> </span><span class="fm">assert!</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
<a id="__codelineno-7-16" name="__codelineno-7-16"></a><span class="p">}</span>
</code></pre></div></td></tr></table></div>
<h3 id="relaxed-ordering">Relaxed Ordering</h3>
<p>While atomic operations using <code>Relaxed</code> memory ordering do not provide any happens-before relationship, they do guarantee a <em>total modification order</em> of each individual atomic variable. This means that all modifications <em>of the same atomic variable</em> happen in an order that is the same from the perspective of every single thread.</p>
<h3 id="release-and-acquire-ordering">Release and Acquire Ordering</h3>
<p><code>Release</code> and <code>Acquire</code> memory ordering are used in a pair to form a happens-before relationship between threads. <code>Release</code> memory ordering applies to <em>store</em> operations, while <code>Acquire</code> memory ordering applies to <em>load</em> operations.</p>
<p>A happens-before relationship is formed when an <strong>acquire-load</strong> operation observes the result of a <strong>release-store</strong> operation. In this case, the store and everything before it, happened before the load and everything after it.</p>
<p>When using <code>Acquire</code> for a <strong>fetch-and-modify</strong> or <strong>compare-and-exchange</strong> operation, it applies only to the part of the operation that <em>loads</em> the value. Similarly, <code>Release</code> applies only to the <em>store</em> part of an operation. <code>AcqRel</code> is used to represent the combination of <code>Acquire</code> and <code>Release</code>, which causes both the <em>load</em> to use <code>Acquire</code> ordering, and the <em>store</em> to use <code>Release</code> ordering.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-8-1"> 1</a></span>
<span class="normal"><a href="#__codelineno-8-2"> 2</a></span>
<span class="normal"><a href="#__codelineno-8-3"> 3</a></span>
<span class="normal"><a href="#__codelineno-8-4"> 4</a></span>
<span class="normal"><a href="#__codelineno-8-5"> 5</a></span>
<span class="normal"><a href="#__codelineno-8-6"> 6</a></span>
<span class="normal"><a href="#__codelineno-8-7"> 7</a></span>
<span class="normal"><a href="#__codelineno-8-8"> 8</a></span>
<span class="normal"><a href="#__codelineno-8-9"> 9</a></span>
<span class="normal"><a href="#__codelineno-8-10">10</a></span>
<span class="normal"><a href="#__codelineno-8-11">11</a></span>
<span class="normal"><a href="#__codelineno-8-12">12</a></span>
<span class="normal"><a href="#__codelineno-8-13">13</a></span>
<span class="normal"><a href="#__codelineno-8-14">14</a></span>
<span class="normal"><a href="#__codelineno-8-15">15</a></span>
<span class="normal"><a href="#__codelineno-8-16">16</a></span>
<span class="normal"><a href="#__codelineno-8-17">17</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1"></a><span class="k">use</span><span class="w"> </span><span class="n">std</span><span class="p">::</span><span class="n">sync</span><span class="p">::</span><span class="n">atomic</span><span class="p">::</span><span class="n">Ordering</span><span class="p">::{</span><span class="n">Acquire</span><span class="p">,</span><span class="w"> </span><span class="n">Release</span><span class="p">};</span>
<a id="__codelineno-8-2" name="__codelineno-8-2"></a>
<a id="__codelineno-8-3" name="__codelineno-8-3"></a><span class="k">static</span><span class="w"> </span><span class="n">DATA</span><span class="p">:</span><span class="w"> </span><span class="nc">AtomicU64</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AtomicU64</span><span class="p">::</span><span class="n">new</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<a id="__codelineno-8-4" name="__codelineno-8-4"></a><span class="k">static</span><span class="w"> </span><span class="n">READY</span><span class="p">:</span><span class="w"> </span><span class="nc">AtomicBool</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">AtomicBool</span><span class="p">::</span><span class="n">new</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<a id="__codelineno-8-5" name="__codelineno-8-5"></a>
<a id="__codelineno-8-6" name="__codelineno-8-6"></a><span class="k">fn</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-7" name="__codelineno-8-7"></a><span class="w"> </span><span class="n">thread</span><span class="p">::</span><span class="n">spawn</span><span class="p">(</span><span class="o">||</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-8" name="__codelineno-8-8"></a><span class="w"> </span><span class="n">DATA</span><span class="p">.</span><span class="n">store</span><span class="p">(</span><span class="mi">123</span><span class="p">,</span><span class="w"> </span><span class="n">Relaxed</span><span class="p">);</span>
<a id="__codelineno-8-9" name="__codelineno-8-9"></a><span class="w"> </span><span class="n">READY</span><span class="p">.</span><span class="n">store</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="n">Release</span><span class="p">);</span><span class="w"> </span><span class="c1">// Everything from before this store ..</span>
<a id="__codelineno-8-10" name="__codelineno-8-10"></a><span class="w"> </span><span class="p">});</span>
<a id="__codelineno-8-11" name="__codelineno-8-11"></a>
<a id="__codelineno-8-12" name="__codelineno-8-12"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="o">!</span><span class="n">READY</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">Acquire</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// .. is visible after this loads `true`.</span>
<a id="__codelineno-8-13" name="__codelineno-8-13"></a><span class="w"> </span><span class="n">thread</span><span class="p">::</span><span class="n">sleep</span><span class="p">(</span><span class="n">Duration</span><span class="p">::</span><span class="n">from_millis</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span>
<a id="__codelineno-8-14" name="__codelineno-8-14"></a><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">&quot;waiting...&quot;</span><span class="p">);</span>
<a id="__codelineno-8-15" name="__codelineno-8-15"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-8-16" name="__codelineno-8-16"></a><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">&quot;{}&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">DATA</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">Relaxed</span><span class="p">));</span>
<a id="__codelineno-8-17" name="__codelineno-8-17"></a><span class="p">}</span>
</code></pre></div></td></tr></table></div>
<h3 id="consume-ordering">Consume Ordering</h3>
<p><code>Consume</code> ordering is a lightweight, more efficient, variant of <code>Acquire</code> ordering, whose synchronizing effects are limited to things that <em>depend on</em> the loaded value.</p>
<p>Now theres good news and bad news.</p>
<p>In all modern processor architectures, <code>Consume</code> ordering is achieved with the exact same instructions as <code>Relaxed</code> ordering. In other words, <code>Consume</code> ordering can be "free," which, at least on some platforms, is not the case for acquire ordering. Unfortunately no compiler actually implements <code>Consume</code> ordering.</p>
<p>The concept of a "dependent" evaluation hard to define, its even harder to keep such dependencies intact while transforming and optimizing a program.</p>
<p>Because of this, compilers upgrade <code>Consume</code> ordering to <code>Acquire</code> ordering, just to be safe. The C++20 standard even explicitly discourages the use of <code>Consume</code> ordering, noting that an implementation other than just <code>Acquire</code> ordering turned out to be infeasible.</p>
<h3 id="sequentially-consistent-ordering">Sequentially Consistent Ordering</h3>
<p>The strongest memory ordering is s<strong>sequentially consistent</strong> ordering (<code>SeqCst</code>). It includes all the guarantees of <code>Acquire</code> ordering (for loads) and <code>Release</code> ordering (for stores), and also guarantees a <em>globally consistent order</em> of operations.</p>
<p>This means that every single operation using <code>SeqCst</code> ordering within a program is part of a single total order that all threads agree on. This total order is consistent with the total modification order of each individual variable.</p>
<p>Since it is strictly stronger than <code>Acquire</code> and <code>Release</code> memory ordering, a sequentially consistent load or store can take the place of an <strong>acquire-load</strong> or <strong>release-store</strong> in a <em>release-acquire</em> pair to form a happens-before relationship. In other words, an <strong>acquire-load</strong> can not only form a happens-before relationship with a <strong>release-store</strong>, but also with a sequentially consistent store, and similarly the other way around.</p>
<p>Virtually all real-world uses of <code>SeqCst</code> involve a pattern of a store that must be globally visible before a subsequent load on the same thread. For these situations, a potentially more efficient alternative is to instead use <code>Relaxed</code> operations in combination with a <code>SeqCst</code> <strong>fence</strong>.</p>
<h3 id="fences">Fences</h3>
<p>The <code>std::sync::atomic::fence</code> function represents an <strong>atomic fence</strong> and is either a release fence (<code>Release</code>), an acquire fence (<code>Acquire</code>), or both (<code>AcqRel</code> or <code>SeqCst</code>). A <code>SeqCst</code> fence additionally also takes part in the sequentially consistent total order.</p>
<p>An atomic fence allows to <em>separate</em> the memory ordering from the atomic operation. This can be useful to apply a memory ordering to <em>multiple</em> operations, or to apply it conditionally.</p>
<p>In essence, a <strong>release-store</strong> can be split into a release fence followed by a (<code>Relaxed</code>) store, and an <strong>acquire-load</strong> can be split into a (<code>Relaxed</code>) load followed by an acquire fence.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-9-1">1</a></span>
<span class="normal"><a href="#__codelineno-9-2">2</a></span>
<span class="normal"><a href="#__codelineno-9-3">3</a></span>
<span class="normal"><a href="#__codelineno-9-4">4</a></span>
<span class="normal"><a href="#__codelineno-9-5">5</a></span>
<span class="normal"><a href="#__codelineno-9-6">6</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1"></a><span class="c1">// The store of a release-acquire relationship</span>
<a id="__codelineno-9-2" name="__codelineno-9-2"></a><span class="n">atom</span><span class="p">.</span><span class="n">store</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">Release</span><span class="p">);</span>
<a id="__codelineno-9-3" name="__codelineno-9-3"></a>
<a id="__codelineno-9-4" name="__codelineno-9-4"></a><span class="c1">// can be substituted by a release fence followed by a relaxed store</span>
<a id="__codelineno-9-5" name="__codelineno-9-5"></a><span class="n">fence</span><span class="p">(</span><span class="n">Release</span><span class="p">);</span>
<a id="__codelineno-9-6" name="__codelineno-9-6"></a><span class="n">atom</span><span class="p">.</span><span class="n">store</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">Relaxed</span><span class="p">);</span>
</code></pre></div></td></tr></table></div>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">Rust</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-10-1">1</a></span>
<span class="normal"><a href="#__codelineno-10-2">2</a></span>
<span class="normal"><a href="#__codelineno-10-3">3</a></span>
<span class="normal"><a href="#__codelineno-10-4">4</a></span>
<span class="normal"><a href="#__codelineno-10-5">5</a></span>
<span class="normal"><a href="#__codelineno-10-6">6</a></span></pre></div></td><td class="code"><div><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1"></a><span class="c1">// The load of a release-acquire relationship,</span>
<a id="__codelineno-10-2" name="__codelineno-10-2"></a><span class="n">atom</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">Acquire</span><span class="p">);</span>
<a id="__codelineno-10-3" name="__codelineno-10-3"></a>
<a id="__codelineno-10-4" name="__codelineno-10-4"></a><span class="c1">// can be substituted by a relaxed load followed by an acquire fence</span>
<a id="__codelineno-10-5" name="__codelineno-10-5"></a><span class="n">atom</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">Relaxed</span><span class="p">);</span>
<a id="__codelineno-10-6" name="__codelineno-10-6"></a><span class="n">fence</span><span class="p">(</span><span class="n">Acquire</span><span class="p">);</span>
</code></pre></div></td></tr></table></div>
<blockquote>
<p><strong>Note</strong>: Using a separate fence can result in an extra processor instruction which can be slightly less efficient.
<strong>Note</strong>: A fence is not tied to any single atomic variable. This means that a single fence can be used for multiple variables at once.</p>
</blockquote>
<p>A release fence can take the place of a release operation in a happens-before relationship if that release fence is followed (on the same thread) by any atomic operation that stores a value observed by the acquire operation it's synchronizing with.<br />
Similarly, an acquire fence can take the place of any acquire operation if that acquire fence is preceded (on the same thread) by any atomic operation that loads a value stored by the release operation.</p>
<p>An happens-before relationship is created between a release fence and an acquire fence if <em>any</em> store after the release fence is observed by <em>any</em> load before the acquire fence.</p>
<p>A <code>SeqCst</code> fence is both a <code>Release</code> fence and an <code>Acquire</code> fence (just like <code>AcqRel</code>), but also part of the single total order of sequentially consistent operations. However, <em>only</em> the fence is part of the total order, but not necessarily the atomic operations before or after it. This means that unlike a release or acquire operation, a sequentially consistent operation <em>cannot</em> be split into a relaxed operation and a memory fence.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="cargo.html" class="md-footer__link md-footer__link--prev" aria-label="Previous: Cargo">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Cargo
</div>
</div>
</a>
<a href="unit-tests.html" class="md-footer__link md-footer__link--next" aria-label="Next: Unit Tests">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Unit Tests
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
MIT
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
<div class="md-social">
<a href="https://hachyderm.io/@m_lamonaca" target="_blank" rel="noopener me" title="hachyderm.io" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M433 179.11c0-97.2-63.71-125.7-63.71-125.7-62.52-28.7-228.56-28.4-290.48 0 0 0-63.72 28.5-63.72 125.7 0 115.7-6.6 259.4 105.63 289.1 40.51 10.7 75.32 13 103.33 11.4 50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.5 102.5 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7 56.12-6.7 105-41.3 111.23-72.9 9.8-49.8 9-121.5 9-121.5m-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175 25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5 11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1 23.71 27.3 18.4 53 18.4 175z"/></svg>
</a>
<a href="https://github.com/m-lamonaca" target="_blank" rel="noopener" title="github.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": ["navigation.instant", "navigation.indexes", "navigation.tracking", "navigation.pruning", "navigation.sections", "navigation.top", "navigation.tabs", "navigation.tabs.sticky", "navigation.footer", "toc.follow", "content.code.copy"], "search": "../../assets/javascripts/workers/search.07f07601.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script src="../../assets/javascripts/bundle.56dfad97.min.js"></script>
</body>
</html>