TCL:thread::send命令在主线程中运行,而不是在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时,switch1会依次调用此proc,switch2会依次调用。在eval_procs中打印thread::id后,我发现这些proc正在主线程中运行,这就是顺序运行的原因。

有人在这里帮助我,我在这里犯了什么错误,或者要遵循任何其他程序?

下面的帖子提到在创建线程时在脚本中定义proc,但对我来说,我有很多已经开发的库(proc(,它们可以很好地与主线程一起工作。因此,我无法移动线程::create下的所有库。

https://stackoverflow.com/a/32154589/13100284

通常,您在主解释器中创建的任何自定义过程(或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]
}

您正在当前线程中执行eval_procs,并将结果发送到要执行的线程。由于eval_procs返回空字符串,线程实际上什么也不做。

你可能想要一个额外的list

thread::send -async [lindex $jointhreadIds $i] 
[list eval_procs [lindex $dutList $i] [lindex $dutConfigList $i]]

但这将失败,因为eval_procs命令在工作线程中是未知的。您必须在每个子线程中定义该过程,而不是在当前子线程中。

最新更新