1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

docs: describe upcoming concurrency

This commit is contained in:
Uwe Krüger 2020-06-28 13:58:08 +02:00 committed by GitHub
parent 0138f46797
commit bc9f8babaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

106
doc/upcoming.md Normal file
View File

@ -0,0 +1,106 @@
# V Work In Progress
***This document describes features that are not implemented, yet.
Please refer to [docs.md](https://github.com/vlang/v/blob/master/doc/docs.md)
for the current state of V***
## Table of Contents
* [Concurrency](#concurrency)
* [Variable Declarations](#concurrency-variable-declarations)
## Concurrency
### Variable Declarations
Objects that are supposed to be used to exchange data between
coroutines have to be declared with special care. Exactly one of the following
4 kinds of declaration has to be chosen:
```v
a := ...
mut b := ...
shared c := ...
atomic d := ...
```
- `a` is declared as *constant* that can be passed to
other coroutines and read without limitations. However
it cannot be changed.
- `b` can be accessed reading and writing but only from one
coroutine. That coroutine *owns* the object. A `mut` variable can
be passed to another coroutine (as receiver or function argument in
the `go` statement or via a channel) but then ownership is passed,
too, and only the other coroutine can access the object.<sup>1</sup>
- `c` can be passed to coroutines an accessed
*concurrently*.<sup>2</sup> In order to avoid data races it has to
be locked before access can occur and unlocked to allow access to
other coroutines. This is done by the following block structure:
```v
lock c {
// read, modify, write c
...
}
```
Several variables may be specified: `lock x, y, z { ... }`.
They are unlocked in the opposite order.
- `d` can be passed to coroutines and accessed *concurrently*,
too.<sup>3</sup> No lock is needed in this case, however
`atomic` variables can only be 32/64 bit integers (or pointers)
and access is limited to a small set of predefined idioms that have
native hardware support.
To help making the correct decision the following table summarizes the
different capabilities:
| | *default* | `mut` | `shared` | `atomic` |
| :--- | :---: | :---: | :---: | :---: |
| write access | | + | + | + |
| concurrent access | + | | + | + |
| performance | ++ | ++ | | + |
| sophisticated operations | + | + | + | |
| structured data types | + | + | + | |
### Strengths
#### default
- very fast
- unlimited access from different coroutines
- easy to handle
#### `mut`
- very fast
- easy to handle
#### `shared`
- concurrent access from different coroutines
- data type may be complex structure
- sophisticated access possible (several statements within one `lock`
block)
#### `atomic`
- concurrent access from different coroutines
- reasonably fast
### Weaknesses
#### default
- read only
#### `mut`
- access only from one coroutine at a time
#### `shared`
- lock/unlock are slow
- moderately difficult to handle (needs `lock` block)
#### `atomic`
- limited to single (max. 64 bit) integers (and pointers)
- only a small set of predefined operations possible
- very difficult to handle correctly
<sup>1</sup> The owning coroutine will also free the memory space used
for the object when it is no longer needed.
<sup>2</sup> For `shared` objects the compiler adds code for reference
counting. Once the counter reaches 0 the object is automatically freed.
<sup>3</sup> Since an `atomic` variable is only a few bytes in size
allocation would be an unnecessary overhead. Instead the compiler
creates a global.