Slide 36 de 74

Concorrência: await

Vários de uma vez, como valor
proc slow(label: Str, ms: Int): Str {
	hive.task.sleep(ms)
	return label
}

proc main(): void {
	both := await [slow("a", 40), slow("b", 40)]   // uma barreira, um Str[2]
	echo both
	echo both[1]                                    // tamanho estático: sem guarda
}
Vários de uma vez, como instrução
proc note(text: Str): void {
	hive.task.sleep(20)
	echo text
}

proc main(): void {
	// Nada em que se resolver, então é uma instrução: um lote de efeitos
	// concluído antes da próxima linha, cada um em sua própria thread.
	await [note("primeiro"), note("segundo")]
	echo "os dois avisos chegaram"
}

await [f(a), g(b)] inicia cada chamada da lista numa thread própria e espera por todas, como uma barreira só. É o único await que existe:

  • Toda entrada precisa ser uma chamada; um valor que já está em mãos não tem pelo que esperar.
  • As chamadas respondem com um só tipo, já que a barreira se resolve em um vetor delas — do tamanho da lista, então seus elementos são indexados sem guarda. Chamadas que respondem de formas diferentes recebem nomes em vez disso, com x := async f().
  • Sobre chamadas que não respondem nada, não há em que se resolver, então é uma instrução: estas, todas elas, e então siga.
  • Um await de uma chamada só é permitido, e await [] é um erro de compilação.

Os argumentos de cada chamada são copiados antes de a thread dela começar, exatamente como com async, e não há como cancelar uma chamada depois que ela começou.