TCL:thread :: send命令正在主线程中运行,而不是发送命令中提到的线程ID

问题描述 投票:0回答:2

下面是为现有的单(主线程)线程脚本实现多线程而编写的示例脚本。

# 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之后,我发现这些proc在主线程中运行,这是顺序运行的原因。

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

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

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

multithreading tcl send
2个回答
0
投票

您正在当前线程中执行eval_procs,并将结果发送给线程以执行。由于eval_procs返回空字符串,因此线程实际上不执行任何操作。

您可能希望在其中添加一个list

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

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


0
投票

通常,您在主解释器中创建的任何自定义过程(或C命令)也会在其他线程的解释器中<>创建。您可以使用Thread包的ttrace system进行复制,但是您需要显式加载所需的任何其他C命令。 (我更喜欢将所需的所有内容放入包中,然后根据需要在每个工作线程中仅包含ttrace,但这更复杂。)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

© www.soinside.com 2019 - 2024. All rights reserved.