1
votes

I have a tcl proc called run_expect that I use to run basic tcl expect flow: spawn <device>, send <cmd>, expect <string>. Now I need to run this code from 2 threads running in parallel, I did the following attemps:

  1. when I tried to write the multi-threaded proc which simply calls run_expect I got the error of unknown command run_expect from the thread's context/scope.
  2. I tried to take the implementation of the run_expect proc and put it in the thread itself, but then I encountered another issue that the thread doesn't seem to see expect library as the other procs and complains on: "invalid command name "spawn".
  3. I tried then to do package require Expect from the thread itself, but got Segmentation fault: 11 error.
  4. Tried to update the ::audio_path variable of the thread to be same as main context but also didn't help making the package require work (::thread::send -async [lindex $tids 0] [list set ::auto_path $::auto_path])

Is there anyway to call any already existing proc from a thread? if not, is moving the code into the thread is the write solution? and how can I get the thread to know the packages / commands loaded?

1
expect is not thread safe. You can't have multiple expect sessions in different threads.Shawn
And each tcl thread is a separate interp, so yeah, you have to load packages, define needed procs and variables, etc. in each one.Shawn

1 Answers

1
votes

Each thread in Tcl is almost totally isolated from all other threads. They don't share any commands (including procedures) or variables. The easiest way to manage things in multiple threads is to put the code to be in each thread into its own Tcl file and to tell the worker threads to source that as part of starting up.

However…

The Expect package is not thread safe; you've provided clear evidence of that. I don't know the details of why this is so. This means that if you want multithreaded expecting, your easiest approach is to use several processes instead. Tcl's good at managing subprocesses via asynchronous pipelines, and when everything is designed to work that way, you don't need to use Expect in the parent to manage things. You could also use the comm package to do the communications with the subprocesses.