From 66c85aa5cb57fc64def1ed47a41d29e0a95d7673 Mon Sep 17 00:00:00 2001 From: Miccah Date: Wed, 24 Feb 2021 03:41:12 -0600 Subject: [PATCH] docs: update concurrency docs and examples to use []thread{} (#8933) --- doc/docs.md | 41 +++++++++++++++------- examples/concurrency/concurrency.v | 15 ++++---- examples/concurrency/concurrency_returns.v | 13 +++++++ 3 files changed, 48 insertions(+), 21 deletions(-) create mode 100644 examples/concurrency/concurrency_returns.v diff --git a/doc/docs.md b/doc/docs.md index 6bc011d32..499be3bd7 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -2566,28 +2566,24 @@ fn main() { } ``` -If there is a large number of tasks that do not return a value it might be easier to manage -them using a wait group. However, for this approach the function(s) called concurrently have -to be designed with this wait group in mind: +If there is a large number of tasks, it might be easier to manage them +using an array of threads. ```v -import sync import time -fn task(id int, duration int, mut wg sync.WaitGroup) { +fn task(id int, duration int) { println('task $id begin') time.wait(duration * time.millisecond) println('task $id end') - wg.done() } fn main() { - mut wg := sync.new_waitgroup() - wg.add(3) - go task(1, 500, mut wg) - go task(2, 900, mut wg) - go task(3, 100, mut wg) - wg.wait() + mut threads := []thread{} + threads << go task(1, 500) + threads << go task(2, 900) + threads << go task(3, 100) + threads.wait() println('done') } @@ -2601,6 +2597,27 @@ fn main() { // done ``` +Additionally for threads that return the same type, calling `wait()` +on the thread array will return all computed values. + +```v +fn expensive_computing(i int) int { + return i * i +} + +fn main() { + mut threads := []thread int{} + for i in 1 .. 10 { + threads << go expensive_computing(i) + } + // Join all tasks + r := threads.wait() + println('All jobs finished: $r') +} + +// Output: All jobs finished: [1, 4, 9, 16, 25, 36, 49, 64, 81] +``` + ### Channels Channels are the preferred way to communicate between coroutines. V's channels work basically like those in Go. You can push objects into a channel on one end and pop objects from the other end. diff --git a/examples/concurrency/concurrency.v b/examples/concurrency/concurrency.v index 31e2c32ea..e681fc7fd 100644 --- a/examples/concurrency/concurrency.v +++ b/examples/concurrency/concurrency.v @@ -1,21 +1,18 @@ -import sync import time // Simulate expensive computing using sleep function -fn expensive_computing(id int, duration int, mut wg sync.WaitGroup) { +fn expensive_computing(id int, duration int) { println('Executing expensive computing task ($id)...') time.wait(duration * time.millisecond) println('Finish task $id on $duration ms') - wg.done() } fn main() { - mut wg := sync.new_waitgroup() - wg.add(3) - go expensive_computing(1, 100, mut wg) - go expensive_computing(2, 500, mut wg) - go expensive_computing(3, 1000, mut wg) + mut threads := []thread{} + threads << go expensive_computing(1, 100) + threads << go expensive_computing(2, 500) + threads << go expensive_computing(3, 1000) // Join all tasks - wg.wait() + threads.wait() println('All jobs finished!') } diff --git a/examples/concurrency/concurrency_returns.v b/examples/concurrency/concurrency_returns.v new file mode 100644 index 000000000..6d687e4f2 --- /dev/null +++ b/examples/concurrency/concurrency_returns.v @@ -0,0 +1,13 @@ +fn expensive_computing(i int) int { + return i * i +} + +fn main() { + mut threads := []thread int{} + for i in 1 .. 10 { + threads << go expensive_computing(i) + } + // Join all tasks + r := threads.wait() + println('All jobs finished: $r') +} -- 2.30.2