multithreading - TCL:thread::send 命令正在主线程中运行,而不是发送命令中提到的线程 id
问题描述
下面是为我现有的单(主线程)线程脚本实现多线程而编写的示例脚本。
# Wrapper proc for executing passed procedure list
proc eval_procs {dut_no procList} {
telnet_dut $dut_no ;# proc to change telnet id to $dut_no
puts "thread id: [thread::id]"
foreach procedure [join [list $procList]] {
eval [join $procedure]
}
}
for {set i 0} {$i <= 1} {incr i} {
lappend jointhreadIds [thread::create]
}
set dutList [list 1 2]
set dutConfigList [list [list "get_port_statistics_mt 1"] [list "c_get_port_statistics_mt 2"]] ;#proc for getting port statistics from switch 1 and 2
for {set i 0} {$i <= 1} {incr i} {
thread::send -async [lindex $jointhreadIds $i] [eval_procs [lindex $dutList $i] [lindex $dutConfigList $i]]
}
为每个开关调用相同的 proc (eval_procs) 创建了两个线程。但是,当使用 thread::send -async 调用 proc 时,此 proc 将依次为 switch1 调用,然后为 switch2 调用。在 eval_procs 中打印 thread::id 后,我发现这些 procs 在主线程中运行,这就是顺序运行的原因。
有人在这里帮助我,我在这里犯了什么错误或任何其他要遵循的程序?
下面的帖子提到在创建线程时在脚本中定义 procs,但对我来说,我有很多已经开发的库 (procs) 可以在主线程中正常工作。所以,我不能移动 thread::create 下的所有库。
解决方案
通常,您在主解释器中创建的任何自定义过程(或 C 命令)都不会在其他线程的解释器中创建。您可以使用 Thread 包的ttrace
系统进行复制,但您需要显式加载所需的任何额外 C 命令。(我更喜欢将所有需要的东西放在包中,然后package require
根据需要放在每个工作线程中,但这更复杂。)
package require Ttrace
# Procedures created in here get replicated to current and future threads
ttrace::eval {
# Wrapper proc for executing passed procedure list
proc eval_procs {dut_no procList} {
telnet_dut $dut_no ;# proc to change telnet id to $dut_no
puts "thread id: [thread::id]"
foreach procedure [join [list $procList]] {
eval [join $procedure]
}
}
# You probably need to create the other commands here; I don't know your code, but you can source them just fine
}
# Now, the rest of your code as normal.
for {set i 0} {$i <= 1} {incr i} {
lappend jointhreadIds [thread::create]
}
set dutList [list 1 2]
set dutConfigList [list [list "get_port_statistics_mt 1"] [list "c_get_port_statistics_mt 2"]]; #proc for getting port statistics from switch 1 and 2
for {set i 0} {$i <= 1} {incr i} {
thread::send -async [lindex $jointhreadIds $i] [eval_procs [lindex $dutList $i] [lindex $dutConfigList $i]]
}
请注意,您可能还有其他错误。最后一个命令冒犯了我,因为它应该使用多列表foreach
并构建命令以使用list
. 在这里,我的意思是它应该是这样的:
foreach t_id $joinThreadIds dut_no $dutList dut_config $dutConfigList {
# I've split the next line in two for even more clarity
thread::send -async $t_id [list \
eval_procs $dut_no $dut_config]
}
推荐阅读
- node.js - 我正在尝试将此加密加密和解密 js 代码转换为 Angular 项目的打字稿
- laravel - 如何在 JSON api 调用(Lazyload、Vuejs、Laravel)上应用过滤器组件
- c++ - 在 C++ 中从我的数据集中打印出训练集和测试集的内容
- elasticsearch - 如何安装logstash插件(logstash-integration-jdbc)
- powershell - Powershell - 使用密钥加密/解密密码
- python - Python递归聚合
- go - 忽略 Go Web 爬虫中的外部链接
- excel - 运行文件选择器后“对象'_Workbook'的方法'SaveAs'失败”
- javascript - 如何使用条件过滤数组并在 JavaScript 中获取包含首选数据的数组?
- ios - 处理较低的iOS版本段控制