并发编程

轻量级并发模型

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)
    }
}

共享规则:

  1. 必须为结构体/数组/映射类型
  2. 读写分别使用 lock / rlock
  3. 通过 shared 声明共享实例