multithreading - tcl 多线程:在循环中多次调用函数的最佳方法
问题描述
我想为循环中的每个函数调用创建一个线程。被调用函数与调用函数在同一个命名空间中,但被调用函数在执行期间从不同的命名空间调用函数。
我是 tcl 的新手,并且一直在寻找其他 SO 多线程解决方案,但它们似乎依赖于将被调用程序本身嵌入到我试图避免的线程中。
我也仅限于 Thread 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
}
}
解决方案
要模拟线程池,您必须考虑以下方面
- 使工人,即
- 与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
构建的三元组发回,以便将错误传播到您可以看到它们的地方。
推荐阅读
- html - 坚持完成基本 Web 开发项目的过程
- kubernetes - 存储在 GKE "etcd" 中的信息是否加密?
- jdbc - LogStash JDBC 输入调度问题 - 是否可以在上一个查询完成后一分钟运行查询
- android - React Native Android:清单合并失败
- javascript - 在悬停菜单上暂停
- azure-data-factory-2 - 获取预定触发器列表
- python - 将“在按钮中”(模板)定义的参数传递给 CRUD 视图
- ionic-framework - Ionic 3 Button 不完全固定在页脚处,它在滚动时移动
- ios - 如何知道焦点元素何时在语音中重新聚焦(iOS)
- flutter - 如何在 Flutter 中制作可重用的 PopupMenuButton