并发编程
轻量级并发模型
V 的并发模型类似 Go,提供两种并发机制:
go foo()
:在轻量级协程中运行(V运行时管理)spawn foo()
:在系统级线程中运行
import math
fn calc(a f64, b f64) {
println(math.sqrt(a*a + b*b))
}
fn main() {
spawn calc(3, 4) // 在新线程中执行
}
spawn
创建系统线程需注意:
- 受 CPU 核心数限制
- 高并发时可能影响性能
- 资源开销大于协程
线程同步
通过 wait()
等待线程完成:
h := spawn calc(3, 4) // 获取线程句柄
h.wait() // 阻塞直到线程结束
获取返回值:
fn hypotenuse(a f64, b f64) f64 {
return math.sqrt(a*a + b*b)
}
g := spawn hypotenuse(54.06, 2.08) // 启动计算
result := g.wait() // 获取结果
批量线程管理
使用线程数组管理并发任务:
mut threads := []thread{}
threads << spawn task(1, 500) // 添加任务1
threads << spawn task(2, 900) // 添加任务2
threads.wait() // 等待所有任务完成
统一收集返回值:
mut threads := []thread int{}
for i in 1..10 {
threads << spawn compute(i) // 批量启动计算
}
results := threads.wait() // 获取所有结果 [1,4,9,...]
通道(Channels)
线程间通信的核心机制:
// 创建通道
unbuf := chan int{} // 无缓冲通道
buf := chan f64{cap: 100} // 缓冲通道(容量100)
// 发送数据
ch <- 42
// 接收数据
value := <- ch
通道操作:
- 关闭通道:
ch.close()
- 安全接收:
data := <-ch or {
println("通道已关闭")
}
- 传播错误:
data := <-ch ?
多路选择(Select)
监控多个通道状态:
select {
a := <-ch1 { /* 处理ch1数据 */ }
ch2 <- value { /* 数据发送成功 */ }
500 * time.millisecond { /* 超时处理 */ }
}
else
分支可立即返回,与超时分支互斥
通道工具方法
// 非阻塞推送
res := ch.try_push(data) // 返回状态码
// 通道属性
len := ch.len // 队列元素数
cap := ch.cap // 通道容量
closed := ch.closed // 关闭状态
共享对象
线程间安全共享数据:
struct Counter {
mut:
value int
}
fn (shared c Counter) increment() {
lock c { // 写锁
c.value++
}
}
fn main() {
shared counter := Counter{}
spawn counter.increment()
rlock counter { // 读锁
println(counter.value)
}
}
共享规则:
- 必须为结构体/数组/映射类型
- 读写分别使用
lock
/rlock
块 - 通过
shared
声明共享实例