Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cours
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Programmation sysytème avancée
cours
Commits
61a4c4d6
Verified
Commit
61a4c4d6
authored
2 months ago
by
orestis.malaspin
Browse files
Options
Downloads
Patches
Plain Diff
added counter
parent
4f068bcd
Branches
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#38982
passed
2 months ago
Stage: test
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
09_pinning.md
+134
-0
134 additions, 0 deletions
09_pinning.md
codes/coroutines-variables/src/main.rs
+0
-2
0 additions, 2 deletions
codes/coroutines-variables/src/main.rs
with
134 additions
and
2 deletions
09_pinning.md
0 → 100644
+
134
−
0
View file @
61a4c4d6
--
title: "Structures auto-référencées et pinning"
author: "Orestis Malaspinas"
date: "2025-03-31"
patat:
slideNumber: true
wrap: true
margins:
left: 10
right: 10
top: auto
slideLevel: 2
images:
backend: kitty
...
# Introduction
## Programme
*
Impossible de stocker des variables au travers de changement d'états
*
Partie 1: ajouter un compteur
*
Partie 2: ajouter des références
*
Partie 3: les structures auto-référencées
*
Partie 4: Pinning
# Partie 1: ajouter un compteur
## Objectif: ajouter un compteur dans notre code async
```
rust
fn
main
()
{
let
mut
executor
=
runtime
::
init
();
executor
.block_on
(
async_main
());
}
coroutine
fn
async_main
()
{
let
mut
counter
=
0
;
println!
(
"Program starting"
);
let
txt
=
http
::
Http
::
get
(
"/600/HelloAsyncAwait"
)
.wait
;
println!
(
"{txt}"
);
counter
+=
1
;
let
txt
=
http
::
Http
::
get
(
"/400/HelloAsyncAwait"
)
.wait
;
println!
(
"{txt}"
);
counter
+=
1
;
println!
(
"Received {} responses."
,
counter
);
}
```
## Problème?
*
`counter`
ne peut pas être partagé actuellement
*
on a une structure (pas de
`counter`
là dedans)
```rust
fn poll(&mut self, waker: &Waker) -> PollState<Self::Output> {
match self.state {
State::Start => {
println!("Program starting");
let fut1 = Box::new(Http::get("/600/HelloAsyncAwait"));
self.state = State::Wait1(fut1);
}
State::Wait1(ref mut future) => match future.poll(waker) {
PollState::Ready(txt) => {
println!("{txt}");
let fut2 = Box::new(Http::get("/400/HelloAsyncAwait"));
self.state = State::Wait2(fut2);
},
State::Wait2(ref mut future) => match future.poll(waker) {
PollState::Ready(txt) => {
println!("{txt}");
self.state = State::Resolved;
break PollState::Ready(String::new());
```
## Solution
*
Ajout d'une "pile" dans
`Coroutine`
*
Stocke un état interne
```rust
struct Coroutine {
stack: Stack,
state: State,
}
struct Stack {
counter: Option<usize>,
}
```
*
A présent
`poll(&mut self, water: &Waker)`
contient
`counter`
*
Pas complètement idéal, car on doit stocker une copie des données dans des structs séparées
*
Chaque changement d'état doit contenir sa propre variable
*
On pourrait faire mieux en stockant que les modifications
## Le compteur 1/
```
rust
State
::
Start
=>
{
self
.stack.counter
=
Some
(
0
);
self
.state
=
State
::
Wait1
(
Box
::
new
(
Http
::
get
(
"/600/HelloAsyncWait"
)));
}
State
::
Wait1
(
ref
mut
f1
)
=>
{
match
f1
.poll
(
waker
)
{
PollState
::
Ready
(
txt
)
=>
{
let
mut
counter
=
self
.stack.counter
.take
()
.unwrap
();
counter
+=
1
;
self
.state
=
State
::
Wait2
(
Box
::
new
(
Http
::
get
(
"/600/HelloAsyncWait"
)));
self
.stack.counter
=
Some
(
counter
);
}
}
State
::
Wait2
(
ref
mut
f2
)
=>
{
match
f2
.poll
(
waker
)
{
PollState
::
Ready
(
txt
)
=>
{
let
mut
counter
=
self
.stack.counter
.take
()
.unwrap
();
counter
+=
1
;
println!
(
"Received {counter} responses"
);
self
.state
=
State
::
Resolved
;
break
PollState
::
Ready
(
String
::
new
());
}
}
```
## Compteur 2/
*
`Start`
: on initialise le compteur
*
`Wait1`
:
*
on
**prend l'ownership**
de la valeur dans le compteur (
`take()`
)
*
on incrémente le compteur
*
on stocke la valeur dans la pile à nouveau
*
`Wait2`
:
*
on
**prend l'ownership**
de la valeur dans le compteur (
`take()`
)
*
on incrémente le compteur
*
on affiche sa velur à l'écran
*
on "nettoie" la valeur (rien besoin de faire, car on a déjà
`None`
dans la pile)
This diff is collapsed.
Click to expand it.
codes/coroutines-variables/src/main.rs
+
0
−
2
View file @
61a4c4d6
...
@@ -97,8 +97,6 @@ impl Future for Coroutine {
...
@@ -97,8 +97,6 @@ impl Future for Coroutine {
self
.stack.writer
=
Some
(
self
.stack.buffer
.as_mut
()
.unwrap
());
self
.stack.writer
=
Some
(
self
.stack.buffer
.as_mut
()
.unwrap
());
println!
(
"Program starting"
);
println!
(
"Program starting"
);
// ---------------------------------
let
fut1
=
Box
::
new
(
Http
::
get
(
"/600/HelloAsyncWait"
));
let
fut1
=
Box
::
new
(
Http
::
get
(
"/600/HelloAsyncWait"
));
self
.state
=
State
::
Wait1
(
fut1
);
self
.state
=
State
::
Wait1
(
fut1
);
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment