Search code examples
multithreadingtcl

Printing diagnostic messages from worker threads in Tcl


I try to begin experimenting with threads. Right now it is a hell of a (bad) experience. I came to the point, where I even try any example I can get on help pages or even man pages. None was working, really none(just the one below in a way). They all do just nothing. However, with a small change in an example from the man page (!) I could get down to at least one of the problems I have: Here is the code:

    package require Thread
        set t1 [thread::create]
        set t2 [thread::create]
        thread::send -async $t1 "set a 1 ; puts test1 " result
        thread::send -async $t2 "set b 2 ; puts test2" result
        for {set i 0} {$i < 2} {incr i} {
            vwait result
            puts $result
        }

This is the code from the example of the Man-page with just two modifications. The first is, i had to put the "package require" there. The second change is more interesting, because I just added the two "puts" in the two threads. Without it, it works (and yes, the only of even all trivial examples, that did run!). With the puts I receive the error msg "Can't find channel stdout". This I would even understand if I would far stretch, that the thread is not even in its own interp und Variable space, but even with seperated library space. However, I doubt it, because every sample uses puts in its thread code, why shouldn't I be able to use it? So, this seems not to be the answer. Besides, this is the example, that at least gave me an error. All other examples, even from this site her, do just nothing. Nothing happens from the time, when it comes to the "vwait" position, while everybody would expect at least some "puts" text.

I use Thread Lib 2.8.8 with Active TCL both 32bit and 64bit under Windows 10, iof that may help. Any idea why my setup reacts obviously so different from anybody elses? :) Thanks in advance.


Solution

  • No resources are shared with worker threads by default, not even the standard channels. They get their own copies of commands and variables, but channels are simply not there. You can use thread::transfer to move a channel to another thread (with some restrictions) but the standard channels simply can't normally be moved at all. That means a simple puts will fail.

    Get the worker threads to return values back to the main thread. Or you could even do this:

    # Assumes you've sent the main thread identity over
    thread::send $mainThread [list puts $msg]