Explain what threads are. Explain why threads are sometimes useful. Explain why threads are sometimes critical or required. Explain threading vs. thread-safety. ''Note:'' There is very little code out there in the "real world" that is actually thread-safe. The gnu C++ lib has unsafe code! Thread behaviour is treacherously platform dependent. ---- Explain how Tk isn't thread-safe, but GUIs never are, and no-one cares, because they always have a single GUI thread, with others as helpers. ---- Explain threading as programming model most like (modified) assembly line. ---- David Gravereaux is expert in Tcl threading. Also, Jean-Luc Fontaine has been thinking about this deeply for his TclPython [] work. Way back in July 1999, Alexandre Ferrieux summed it up nicely ... This is related to something I've realized only recently with the Tcl threading model: a purposeful, strong isolations of threads. At the beginning, I believed that "at most one thread by interp" was a dirty hack to hide bad reentrancy in the core. Now I have come to understand that instead, it pushes forward a new (as compared to C, as you mentioned) and also very "Tclish" style: basically, Tcl threads are nearly as isolated as *processes*, which is nice because it means all the modularity and atomic-testing we want, without the fork/exec and address space switch overhead !' For the full posting see [http://groups.google.com/groups?q=&selm=377C9ED8.6032%40cnet.francetelecom.fr] ---- Explain Tcl (and Tk) generation options. ---- [http://www.sunworld.com/unixinsideronline/swol-02-2001/swol-0216-regex.html] remarks on history and use of Tcl, particularly as compared to Perl and Python. It also references [John Ousterhout]'s argument [http://www.scriptics.com/people/john.ousterhout/threads.ps] for event-based programming in favor of threading. ---- Point to books, tutorials, online references, etc. on best practices for thread design and programming considerations. ---- Point to critical info on testing (and debugging!) threaded apps. ---- Extensions and threading ... * The '''Thread''' extension (at SourceForge, under the tcl project [http://sourceforge.net/project/tcl]) lifts the threading capabilities of the Tcl C-API into the scriptlevel. ---- Remember: "You may have more than one interp per thread, but never is one interp shared _across_ threads," as David Gravereaux posted to comp.lang.tcl. ---- Until the generation procedures are cleaned up, workers in this area will need to be familiar with "-DTCL_THREADS=1". ---- History of Tcl threads: [Steve Jankowski] released "mttcl" [http://www.ensta.fr/internet/solaris/mttcl.html] in 19??. [D. Richard Hipp] ... [Jim Davidson]'s work for [NaviServer] ... ---- [Zoran Vasiljevic] makes the interesting point that "If you have many threads, load Tcl interpreter in each of them and then load a module in each interpreter, then your references to a global hash table will definitely go to the same table instance. Which means you need to protect access to this table with a mutex. If you need separate tables, i.e. you need not share hash-table data between threads, then you should put the table in thread-specific data structure (TSD), so each thread gets its own copy You would also like to register some thread-exit handler which takes care about finalizing those tables on thread exit, otherwise you'll lose memory." ---- '''A Cookbook Approach''' ''How to use the Thread2.1 package'' #!/bin/sh #\ exec tclsh "$0" "$@" package require Thread 2.1 # # Start a thread. If you will be running many long running commands # at the same time, just create multiple threads identical to this one, and # keep track of the threadID's. # set threadID [thread::create { # # From here to the 'thread::wait' statement, define the procedure(s) # that will be called from your main program (which, btw, is thread #1) # # In this case, I've defined a simple procedure that executes the command # passed into this thread. This command could be an external program or # long running tcl command. # # The result is then sent back to the main program (thread 1) via a call # to a procedure in thread 1. In this example, it's a procedure defined # at the global level. # # The 'thread::wait' is required to keep this thread alive indefinitely. # proc runCommand { ID command } { set result [eval $command] eval [subst {thread::send -async $ID \ {::printResult [list $result]}}] } thread::wait }] # # Here is the procedure that gets called from the thread when the thread # has completed its work. # proc printResult { result } { puts $result exit } proc passTheTime { } { puts [clock format [clock seconds]] after 1000 passTheTime } # # Here we define a sample command, and pass it into the previously started # thread. # set commandString "exec du -sk /usr/local" eval [subst {thread::send -async $threadID \ {runCommand 1 [list $commandString ]}}] # # In this example, lets just pass the time until the thread is complete # passTheTime vwait forever Marty Backe 21 Feb 2002 ---- [tclguy] "just wanted to note that I have found the intermixing of thread-enabled and disabled Tcl and extensions to actually be acceptable in most contexts where only one thread was used, or if other Tcl-level threads were created, they were only used for Tcl." Which statement, while true, requires a lawyer to determine whether it has any significance relative to a project using threads. It sounds like you're saying "if you don't use threads intentionally, the multi-threading Tcl will not bite you otherwise". Is that right? I mean, is that what you meant to say; I don't think you actually know if it's right.