【far 语言】并发编程(协程)

本文是「far 语言」系列文档之一,总目录见《【far 语言】语言文档目录》。

并发:虚拟线程 + Channel

Far 的所有异步任务统一为虚拟线程vtNew),通信只走 Channelselect 多路等待。协作式调度 + 挂起式 IO——recv/accept/sleep 写法与阻塞式一字不差,却不卡调度线程。

创建通道

map<string, object> ch = chanPair();     // 返回 {tx, rx, chan}
map<string, object> tx = ch.tx;          // 发送端点
map<string, object> rx = ch.rx;          // 接收端点

虚拟线程:vtNew

// 匿名方法闭包:端点由闭包捕获,任务收消息后回传确认
map<string, object> ch = chanPair();
map<string, object> tx = ch.tx;
map<string, object> rx = ch.rx;
map<string, object> ack = chanPair();
map<string, object> ackTx = ack.tx;
map<string, object> ackRx = ack.rx;

map<string, object> t = vtNew((dummy)->{
    string msg = chanRecv(rx);
    println("worker got: " + msg);
    chanSend(ackTx, 1);          // 回传确认
}, 0, 0, "worker");
vtStart(t);

chanSend(tx, "hello-from-main");
long ackv = chanRecv(ackRx);     // ackv = 1
  • vtNew(目标, 参数, noSwitch[, 线程名])
  • 目标:匿名方法 (x)->{...} / 闭包变量 / 方法名字符串(如 vtNew("sender", ch, 0, "s1")
  • noSwitch0 可切换 / 1 不可切换(独占运行到完成)
  • vtStart(t) 启动,vtJoin(t) 等待完成,vtAlive(t) 查状态。
  • 结果显式走 Channel 回传(Go 风格),无 spawn / async / await。

Channel 收发

chanSend(tx, msg);              // 发送(无界,不阻塞)
v := chanRecv(rx);           // 阻塞接收(无消息时协程让出)
t := chanRecvTimeout(rx, 100);  // 带超时接收
chanClose(tx);                  // 关闭端点
chanIsClosed(tx);               // 是否已关闭

select 多路等待

select {
    case msg = cmd_rx.recv() => {
        if (msg == "quit") { break; }
    }
    case data = data_rx.recv() => { ... }
    timeout(100) => { }          // 超时分支,可选,放最后
}
  • case 变量 = rx.recv() 仅支持接收端点。
  • 多条就绪随机选一条执行(同 Go select)。
  • 不带 timeout 则永久阻塞。

协程 API

函数 说明
vtNew(...) / vtStart / vtJoin 创建 / 启动 / 等待完成
vtSleep(ms) 协程睡眠(让出,到期恢复)
vtAlive / vtInterrupt / vtCancel 状态 / 中断 / 取消
vtSchedule(fn, arg, name, delay, period) 定时 / 周期任务
vtPollWait(fd, timeout_ms) 挂起等 fd 就绪(挂起式 IO 核心)

完整示例

class App {
    static long main(string args[]){
        map<string, object> ch = chanPair();
        map<string, object> tx = ch.tx;
        map<string, object> rx = ch.rx;

        map<string, object> t = vtNew((dummy)->{
            long sum = 0;
            for(long i = 0; i < 100; i++){ sum = sum + i; }
            chanSend(tx, sum);
        }, 0, 0, "worker");
        vtStart(t);

        long r = chanRecv(rx);       // r = 4950
        println(r);
        return 0;
    }
}
posted @ 2026-09-13 05:05  方东信  阅读(5)  评论(0)    收藏  举报