Você está na página 1de 4

Não da pra gerar threads(segmentos) em go logo em V tbm não da

Shared Objects - compartilhamentos

Os dados podem ser trocados entre um segmento e o segmento de chamada através de uma
variável compartilhada. Tais variáveis devem ser criadas como compartilhadas e passadas para
o segmento como tal, também. A estrutura subjacente contém um mutex oculto que permite
bloquear o acesso simultâneo usando rlock apenas para leitura e bloqueio para acesso à
leitura/gravação.

struct St {

mut:
x int // dado a ser compartilhado
}

fn (shared b St) g() {


lock b {
// read/modify/write b.x
}
}

fn main() {
shared a := St{
x: 10
}
go a.g()
// ...
rlock a {
// read a.x

Além disso, para threads que retornam o mesmo tipo, chamar a wait() no array thread
retornará todos os valores computados.

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]

Concurrency AQII

Spawning Concurrent Tasks


O modelo de concorrência de V será muito semelhante ao do Go. Por enquanto, go
foo() executa foo() simultaneamente em um segmento diferente:
import math

fn p(a f64, b f64) { // função ordinária sem valor de retorno


c := math.sqrt(a * a + b * b)
println(c)
}

fn main() {
go p(3, 4)
// p será executado em segmento paralelo
// Também pode ser escrito da seguinte forma
// go fn (a f64, b f64) {
// c := math.sqrt(a * a + b * b)
// println(c)
// }(3, 4)
}
In V 0.4 go foo() will be automatically renamed via vfmt to spawn foo(), and
there will be a way to launch a coroutine (a lightweight thread managed by the
runtime).

Às vezes é necessário esperar até que um fio paralelo tenha terminado. Isso pode ser
feito atribuindo uma handle ao segmento iniciado e chamando o método de espera =
wait() 😊, para este handle mais tarde:
import math

fn p(a f64, b f64) { // ordinary function without return value


c := math.sqrt(a * a + b * b)
println(c) // prints `5`
}

fn main() {
h := go p(3, 4)
// p() runs in parallel thread
h.wait()
// p() has definitely finished
}
Essa abordagem também pode ser usada para obter um valor de retorno de uma função
que é executada em um segmento paralelo. Não há necessidade de modificar a função
em si para poder chamá-la simultaneamente.
import math { sqrt }

fn get_hypot(a f64, b f64) f64 { // função ordinária devolvendo um


valor
c := sqrt(a * a + b * b)
return c
}

fn main() {
g := go get_hypot(54.06, 2.08) // spawn thread and get handle to it
h1 := get_hypot(2.32, 16.74) // do some other calculation here
h2 := g.wait() // get result from spawned thread
println('Results: $h1, $h2') // prints `Results: 16.9, 54.1`
}
Se houver um grande número de tarefas, pode ser mais fácil gerenciá-las usando uma
matriz de threads.
import time

fn task(id int, duration int) {


println('task $id begin')
time.sleep(duration * time.millisecond)
println('task $id end')
}

fn main() {
mut threads := []thread{}
threads << go task(1, 500)
threads << go task(2, 900)
threads << go task(3, 100)
threads.wait()
println('done')
}

// Output:
// task 1 begin
// task 2 begin
// task 3 begin
// task 3 end
// task 1 end
// task 2 end
// done

Além disso, para threads que retornam o mesmo tipo, chamar a wait() no array thread
retornará todos os valores computados.
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]

Você também pode gostar