You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Julia中让函数在不同线程上运行?异步任务同线程执行问题求解

如何让Julia函数在不同的独立核心/线程上异步并行执行?

我希望在独立核心上运行一个函数,因此编写了一段脚本尝试异步并行执行该函数两次,但运行后发现两次执行都在同一个线程上。

我的代码如下:

const results = Channel()
function my_function()
    delay = rand() * 5
    @info "Task with $delay s"
    @info "Thread $(Threads.threadid())"
    sleep(delay)
    put!(results, delay)
end
errormonitor(@async my_function())
errormonitor(@async my_function())
@info "returned $(take!(results))"
@info "returned $(take!(results))"

运行后的输出:

[ Info: Task with 2.9497522378270298 s
[ Info: Task with 4.956428193185428 s
[ Info: Thread 1
[ Info: Thread 1
[ Info: returned 2.9497522378270298
[ Info: returned 4.956428193185428

请问如何让my_function在不同的线程上运行?


解决方法:切换到Julia的多线程任务调度机制

你碰到的核心问题是:@async宏只是在同一个线程的异步任务队列里调度任务,它本质上还是单线程内的异步,并不会把任务分配到不同的CPU核心/线程上。要实现真正的跨线程并行,得用Julia专门的多线程工具:

第一步:确保Julia以多线程模式启动

在启动Julia的时候,必须指定要使用的线程数,不然默认是单线程运行。常用的两种方式:

  • 命令行启动时直接指定:julia --threads auto(让Julia自动匹配你的CPU核心数)
  • 或者先设置环境变量再启动:export JULIA_NUM_THREADS=4(数字可以根据你的核心数调整,比如4核就设4)

第二步:用Threads.@spawn替换@async

Threads.@spawn会把任务提交到Julia的全局多线程任务池,调度器会自动把这些任务分配到不同的工作线程上执行。修改后的代码如下:

const results = Channel()
function my_function()
    delay = rand() * 5
    @info "Task with $delay s"
    @info "Thread $(Threads.threadid())"
    sleep(delay)
    put!(results, delay)
end
errormonitor(Threads.@spawn my_function())
errormonitor(Threads.@spawn my_function())
@info "returned $(take!(results))"
@info "returned $(take!(results))"

运行这段代码,你应该会看到两次任务分别运行在不同的线程(比如Thread 1和Thread 2),真正利用多核并行。

备选方案:用Threads.@threads处理批量任务

如果需要多次执行同一个函数,Threads.@threads循环也是个不错的选择,它会自动把循环迭代分配到不同线程:

const results = Channel(2) # 提前指定通道容量,避免阻塞
function my_function()
    delay = rand() * 5
    @info "Task with $delay s"
    @info "Thread $(Threads.threadid())"
    sleep(delay)
    put!(results, delay)
end

Threads.@threads for _ in 1:2
    my_function()
end

@info "returned $(take!(results))"
@info "returned $(take!(results))"

补充说明:为什么@async不行?

@async创建的是单线程异步任务,这些任务会在当前线程的事件循环中交替执行(看起来是“并行”,但其实是同一个线程在切换任务),并没有真正用到多个CPU核心。而Threads.@spawn和Threads.@threads才是Julia用来实现真并行的工具,它们能把任务分发到不同的线程,同时利用多个核心的计算能力。


内容的提问来源于stack exchange,提问作者Alexander Rakhmaev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 12:27:48