tcl多线程:在循环中多次调用函数的最佳方式



我想为循环中的每个函数调用创建一个线程。被调用者函数与调用者函数在同一命名空间中,但被调用者函数在执行过程中会从不同的命名空间调用函数。

我是tcl的新手,一直在研究其他SO多线程解决方案,但它们似乎依赖于将被调用者进程本身嵌入线程中,而我正试图避免这种情况。

我也仅限于线程2.7.3,因此线程池不幸不是一个选项。

我也在考虑创建可以并行运行的多个子流程,以更容易的为准,但我想知道解决这个问题的最佳/最简单的方法。提前感谢!

proc process_all_scenarios_multithreaded {results_folder} {
package require Thread 2.7.3
set curr_dir [pwd]
cd $results_folder
foreach scenario $scenario_list {           
#package require dai                
set sname $scenario'
puts "Scenario: $sname"          
set sdir "$curr_dir/$results_folder/$sname"
puts "Results from: $sdir"          
set status SUCCESS
set id [thread::create -joinable]
puts "*** Started thread $id"
thread::send -async $id "extract_system_kpis $sname $status $sdir"
lappend threadIds $id       
}
# Wait until all other threads are finished
foreach id $threadIds {
thread::join $id
}
}

要模拟线程池,必须考虑

  1. 制造工人
  2. 与所述主机通信以获取工作分组
  3. 执行工作,然后
  4. 在提取下一个工作项之前,将结果发送回master

您可以根据要分配给池的资源来调整工作人员的数量。通信可以通过您想要的任何机制进行,但使用thread::send可以在线程之间以及通过管道或套接字发送Tcl列表的进程之间很好地工作。Tcl支持双向管道,所以这样做很容易。

通过管道发送消息只是一件事:

puts $pipe [list ...]
flush $pipe

接收更为复杂,因为你想读行,直到你有一个完整的列表(根据info complete(。

set accumulator ""
while {1} {
append accumulator [gets $pipe] "n"
if {[info complete $accumulator]} {
process $accumulator
set accumulator ""
} elseif {[eof $pipe]} {
break
}
}

您可能希望eval接收到的消息,并将结果代码、结果消息和$::errorInfo作为构建的三元组发回,以便将错误传播到您可以看到它们的位置。

最新更新