如何在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
相关产品推荐
相关产品推荐

