至今我们学习的都是 “共享内存多线程” 的并发模型
优点
缺点
科普一些大家在编程中常见的并发模型
现代编程语言几乎内置都了线程支持
// Kotlin code
class SimpleRunnable: Runnable {
public override fun run() {
println("${Thread.currentThread()} has run.")
}
}
Thread(SimpleRunnable()).start()
thread(start = true) {
println("${Thread.currentThread()} has run.")
}
多个可以保存/恢复的执行流
def all_integers():
i = 0
while True:
yield (i := i + 1)
for i in filter(lambda x: x % 2, all_integers()):
print(i)
>>> all_integers
<function all_integers at 0x108bb40d0>
>>> all_integers()
<generator object all_integers at 0x108c8cf90>
x = yield
协程:有限的并发和并行
线程:并发、并行
实际系统中会遇到的情况
read()
长时间等待 (例如网络)Go: 小孩子才做选择,多处理器并行和轻量级并发我全都要!
Goroutine: 概念上是线程 (可以并行执行)
实现:每个 CPU 上有一个 Go Worker,自由调度 goroutines
例子
Do not communicate by sharing memory; instead, share memory by communicating. ——Effective Go
共享内存 = 万恶之源
既然生产者-消费者能解决绝大部分问题,提供一个 API 不就好了?
异步编程:单线程前台 + 多线程后台
$.ajax( { url: 'http://xxx.yyy.zzz/1',
success: function(resp) {
$.ajax( { url: 'http://xxx.yyy.zzz/2',
success: function(resp) {
// do something
},
error: function(req, status, err) { ... }
}
},
error: function(req, status, err) { ... }
);
好处
坏处
导致 callback hell 的本质:人类脑袋里想的是 “流程图”,看到的是 “回调”。
The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
Chaining
loadScript("/article/promise-chaining/one.js")
.then( script => loadScript("/article/promise-chaining/two.js") )
.then( script => loadScript("/article/promise-chaining/three.js") )
.then( script => {
// scripts are loaded, we can use functions declared there
})
.catch(err => { ... } );
Fork-join
a = new Promise( (resolve, reject) => { resolve('A') } )
b = new Promise( (resolve, reject) => { resolve('B') } )
c = new Promise( (resolve, reject) => { resolve('C') } )
Promise.all([a, b, c]).then( res => { console.log(res) } )
async function
Promise
objectasync_func()
- forkawait promise
await promise
- joinA = async () => await $.ajax('/hello/a')
B = async () => await $.ajax('/hello/b')
C = async () => await $.ajax('/hello/c')
hello = async () => await Promise.all([A(), B(), C()])
hello()
.then(window.alert)
.catch(res => { console.log('fetch failed!') } )
本次课内容与目标
Take-away messages