- Julia 1.0 Programming Complete Reference Guide
- Ivo Balbaert Adrian Salceanu
- 512字
- 2021-06-24 14:21:47
Tasks
Julia has a built-in system for running tasks, which are, in general, known as coroutines. With this, a computation that generates values into a Channel (with a put! function) can be suspended as a task, while a consumer task can pick up the values (with a take! function). This is similar to the yield keyword in Python.
As a concrete example, let's take a look at a fib_producer function that calculates the first 10 Fibonacci numbers (refer to the Recursive functions section in Chapter 3, Functions), but it doesn't return the numbers, it produces them:
# code in Chapter 4\tasks.jl function fib_producer(c::Channel) a, b = (0, 1) for i = 1:10 put!(c, b) a, b = (b, a + b) end end
Construct a Channel by providing this function as an argument:
chnl = Channel(fib_producer)
The task's state is now runnable. To get the Fibonacci numbers, start consuming them with take! until Channel is closed, and the task is finished (state is :done):
take!(chnl) #> 1 take!(chnl) #> 1 take!(chnl) #> 2 take!(chnl) #> 3 take!(chnl) #> 5 take!(chnl) #> 8 take!(chnl) #> 13 take!(chnl) #> 21 take!(chnl) #> 34 take!(chnl) #> 55 take!(chnl) #> ERROR: InvalidStateException("Channel is closed.", :closed)
It is as if the fib_producer function was able to return multiple times, once for each take! call. Between calls to fib_producer, its execution is suspended, and the consumer has control.
The same values can be more easily consumed in a for loop, where the loop variable becomes one by one the produced values:
for n in chnl
println(n) end
This produces: 1 1 2 3 5 8 13 21 34 55.
There is a macro @task that does the same thing:
chnl = @task fib_producer(c::Channel)
Coroutines are not executed in different threads, so they cannot run on separate CPUs. Only one coroutine is running at once, but the language runtime switches between them. An internal scheduler controls a queue of runnable tasks and switches between them based on events, such as waiting for data, or data coming in.
Here is another example, which uses @async to start a task asynchronously, binds a channel to the task, and then prints out the contents of the channel:
fac(i::Integer) = (i > 1) ? i*fac(i - 1) : 1 c = Channel(0) task = @async foreach(i->put!(c,fac(i)), 1:5) bind(c,task) for i in c @show i end
This prints out the following:
i = 1
i = 2
i = 6
i = 24
i = 120
Tasks should be seen as a form of cooperative multitasking in a single thread. Switching between tasks does not consume stack space, unlike normal function calls. In general, tasks have very low overhead; so you can use lots of them if needed. Exception handling in Julia is implemented using Tasks as well as servers that accept many incoming connections (refer to the Working with TCP sockets and servers section in Chapter 8, IO, Networking, and Parallel Computing).
True parallelism in Julia is discussed in the Parallel operations and computing section of Chapter 8, IO, Networking, and Parallel Computing.
- Data Visualization with D3 4.x Cookbook(Second Edition)
- LabVIEW2018中文版 虛擬儀器程序設(shè)計(jì)自學(xué)手冊
- 假如C語言是我發(fā)明的:講給孩子聽的大師編程課
- 概率成形編碼調(diào)制技術(shù)理論及應(yīng)用
- Python完全自學(xué)教程
- Mastering ServiceNow(Second Edition)
- MongoDB,Express,Angular,and Node.js Fundamentals
- 第一行代碼 C語言(視頻講解版)
- 基于ARM Cortex-M4F內(nèi)核的MSP432 MCU開發(fā)實(shí)踐
- Python 3 數(shù)據(jù)分析與機(jī)器學(xué)習(xí)實(shí)戰(zhàn)
- OpenCV Android Programming By Example
- Tableau Desktop可視化高級應(yīng)用
- ROS機(jī)器人編程實(shí)戰(zhàn)
- Raspberry Pi Blueprints
- iOS Development with Xamarin Cookbook