TCL: команда thread :: send выполняется в основном потоке вместо идентификатора потока, указанного в команде send - PullRequest
0 голосов
/ 22 марта 2020

Ниже приведен пример сценария, написанного для реализации многопоточности для моих существующих однопоточных (основных потоков) сценариев.

# 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]]             
}

Два потока созданы для вызова одного и того же pro c (eval_procs) для каждого переключатель. Но когда pro c вызывается с использованием thread :: send -asyn c, этот pro c вызывается последовательно для switch1 и позже для switch2. После печати thread :: id в eval_procs я обнаружил, что эти процессы запущены в основном потоке, что является причиной для последовательного запуска.

Любой, кто поможет мне здесь, какую ошибку я здесь делаю или любую другую Процедура, которой нужно следовать?

В приведенном ниже посте упоминается определение процедур в сценарии при создании потока, но для меня у меня есть так много уже разработанных библиотек (процедур), которые прекрасно работают с основным потоком. Поэтому я не могу переместить все библиотеки в потоке :: create.

{ ссылка }

Ответы [ 2 ]

1 голос
/ 22 марта 2020

Как правило, любые пользовательские процедуры (или C команды), которые вы создаете в главном интерпретаторе, не также создаются в интерпретаторах других потоков. Вы можете использовать ttrace system пакета Thread для репликации, но вам нужно явно загружать любые дополнительные команды 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 и собирать команду для go для другого потока с 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]
}
0 голосов
/ 22 марта 2020

Вы выполняете eval_procs в текущем потоке и отправляете результат в потоки для выполнения. Поскольку eval_procs возвращает пустую строку, потоки фактически ничего не делают.

Возможно, вам понадобится дополнительная list там:

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

Но это не удастся, потому что eval_procs команда не известна в рабочих потоках. Вам нужно будет определить это pro c в каждой из подпотоков, а не в текущей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...