如何获取Tcl多线程的已完成运行结果并捕获首个完成的线程?
Tcl多线程:捕获首个完成线程与获取运行结果
我来帮你搞定这两个Tcl多线程的问题~
一、为什么你的代码无法捕获首个完成的线程?
你当前用foreach配合thread::join的写法是顺序阻塞的:
foreach TID {$TID1 $TID2} { set FID [thread::join $TID] puts "threads finished => $FID" }
这段代码会先阻塞等待TID1完成,之后才会去处理TID2,完全没法感知哪个线程先结束。哪怕TID2先完成,主线程也得等TID1结束后才会发现。
另外从你提供的运行结果看,实际是T1先完成(16:03:30结束),T2是后结束的(16:03:32),你之前的判断有点小偏差哦~
二、正确捕获首个完成线程的方法
用thread::wait命令就可以实现!这个命令会同时等待指定的多个线程,只要其中任意一个完成,就立即返回该线程的ID,不会按顺序阻塞。
示例代码:
# 等待任意一个线程完成,返回首个完成的线程ID set finished_tid [thread::wait $TID1 $TID2] puts "首个完成的线程是: $finished_tid" # 处理剩下未完成的线程 set remaining_tid [expr {$finished_tid eq $TID1 ? $TID2 : $TID1}] thread::join $remaining_tid puts "剩余线程也已完成: $remaining_tid"
三、如何获取线程的运行结果?
Tcl线程默认不会主动返回运行结果,你可以通过两种常用方式获取:
方式1:让线程退出时返回结果,用thread::join接收
修改你的线程创建代码,在线程末尾用return返回结果,之后thread::join就能拿到这个返回值:
set TID1 [thread::create -joinable { proc DATE {} {clock format [clock scan [exec date]] -format {%m%b%y-%H:%M:%S}} puts "start T1-: [DATE]" # 存储线程运行结果 set run_result "" for {set i 0} {$i < 3} {incr i} { exec sleep 1 puts "run T1 $i" append run_result "T1 执行步骤 $i;" } puts "end T1---: [DATE]" # 线程退出时返回结果 return $run_result }] set TID2 [thread::create -joinable { proc DATE {} {clock format [clock scan [exec date]] -format {%m%b%y-%H:%M:%S}} puts "start T2-: [DATE]" set run_result "" for {set j 0} {$j < 5} {incr j} { exec sleep 1 puts "run T2 $j" append run_result "T2 执行步骤 $j;" } puts "end T2---: [DATE]" return $run_result }]
然后在主线程中获取结果:
set finished_tid [thread::wait $TID1 $TID2] # 获取首个完成线程的结果 set finished_result [thread::join $finished_tid] puts "首个完成线程($finished_tid)的结果: $finished_result" # 获取剩余线程的结果 set remaining_tid [expr {$finished_tid eq $TID1 ? $TID2 : $TID1}] set remaining_result [thread::join $remaining_tid] puts "剩余线程($remaining_tid)的结果: $remaining_result"
方式2:使用共享变量存储结果
通过thread::shared创建全局共享数组,让线程把结果写入这个数组,主线程随时可以读取:
# 创建共享数组,用于存储各线程的结果 thread::shared ::thread_results set TID1 [thread::create -joinable { proc DATE {} {clock format [clock scan [exec date]] -format {%m%b%y-%H:%M:%S}} puts "start T1-: [DATE]" set run_result "" for {set i 0} {$i < 3} {incr i} { exec sleep 1 puts "run T1 $i" append run_result "T1 执行步骤 $i;" } puts "end T1---: [DATE]" # 将结果存入共享数组,用线程ID作为键 set ::thread_results([thread::id]) $run_result }] set TID2 [thread::create -joinable { proc DATE {} {clock format [clock scan [exec date]] -format {%m%b%y-%H:%M:%S}} puts "start T2-: [DATE]" set run_result "" for {set j 0} {$j < 5} {incr j} { exec sleep 1 puts "run T2 $j" append run_result "T2 执行步骤 $j;" } puts "end T2---: [DATE]" set ::thread_results([thread::id]) $run_result }]
主线程中读取结果:
set finished_tid [thread::wait $TID1 $TID2] puts "首个完成线程($finished_tid)的结果: $::thread_results($finished_tid)" # 等待剩余线程完成后读取结果 thread::join [expr {$finished_tid eq $TID1 ? $TID2 : $TID1}] set remaining_tid [expr {$finished_tid eq $TID1 ? $TID2 : $TID1}] puts "剩余线程($remaining_tid)的结果: $::thread_results($remaining_tid)"
内容的提问来源于stack exchange,提问作者cyl cyl
相关产品推荐
相关产品推荐

