Training, Open Source computer languages
PerlPHPPythonMySQLApache / TomcatTclRubyJavaC and C++LinuxCSS 
Search for:
Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
For 2023 (and 2024 ...) - we are now fully retired from IT training.
We have made many, many friends over 25 years of teaching about Python, Tcl, Perl, PHP, Lua, Java, C and C++ - and MySQL, Linux and Solaris/SunOS too. Our training notes are now very much out of date, but due to upward compatability most of our examples remain operational and even relevant ad you are welcome to make us if them "as seen" and at your own risk.

Lisa and I (Graham) now live in what was our training centre in Melksham - happy to meet with former delegates here - but do check ahead before coming round. We are far from inactive - rather, enjoying the times that we are retired but still healthy enough in mind and body to be active!

I am also active in many other area and still look after a lot of web sites - you can find an index ((here))
Multi-threaded TCL -- HELPPPP

Posted by mawardi (mawardi), 2 June 2005
Hello guys, seriously in need of help ...

I want to test out the thread capability of TCL ... and i got one example from Brent (http://beedub.com/book/4th/Threads.pdf) ...

inside there is a TCL multi-threaded echo server script (example 21-12) ...

But when i try it ... there are so many unexplained things happening ... like bugs in threading ...

here is the code plus the COMMENTS that where the weird things happend .. i hope someone can explain it to me why ....


Code:
   package require Tcl 8.4
   package require Thread

   if {$argc > 0} {
       set port [lindex $argv 0]
   } else {
       set port 9001
   }


   socket -server _ClientConnect $port

   proc _ClientConnect {sock host port} {
       puts  "Accept $sock from $host port $port"
       after 0 [list ClientConnect $sock $host $port]
   }

   proc ClientConnect {sock host port} {

       set threadID [thread::create {

           proc ReadLine {sock} {
               #WHY THIS LINE CAUSED ERROR !!!!
               #puts "got event";

               #WHY IT RETURN THE MASTER THREAD ID AND NOT THE CHILD THREAD ID!!!!
               SendMessage $sock "Thread [thread::id] receive an event .."
               if {[catch {gets $sock line} len] || [eof $sock]} {
                   catch {close $sock}
                   thread::release
               } else {
                   EchoLine $sock $line
               }
           }

           proc EchoLine {sock line} {
               #WHY IT RETURN THE MASTER THREAD ID !!!!
               if {[string equal -nocase $line quit]} {
                   SendMessage $sock "Closing connection to Echo server"
                   SendMessage $sock "Thread [thread::id] is about to be release"
                   #WHY CLOSE THIS SOCKET WILL KILL THE WHOLE SERVER !!!!!
                   catch {close $sock}
                   #WHY REALEASING THIS THREAD, IT STILL RESPONDING TO THE CLIENT (if we dont put the close $sock)
                   thread::release
               } else {
                   SendMessage $sock $line
               }
           }

           proc SendMessage {sock msg} {
               #WHY IT SEND THE MASTER THREAD ID !!!!
               if {[catch {puts $sock "[thread::id] >> $msg"} error]} {
                   puts stderr "Error writing to socket: $error"
                   catch {close $sock}
                   thread::release
               }
           }

           proc getSock {sock} {
               thread::attach $sock
               fconfigure $sock -buffering line -blocking 0
               fileevent $sock readable [list ReadLine $sock]
               #WHY STDOUT HERE IS RECOGNIZABLE !
               puts "Thread [thread::id] say hello"

           }

           puts "[thread::id] running\n";
           thread::wait
       }]


       thread::detach $sock

       puts "*** Started thread $threadID"
       puts "*** Master Thread [thread::id]"
       puts "*** Existing threads: [thread::names]"


       thread::send -async $threadID [list set sock $sock]
       thread::send -async $threadID [list set mTID [thread::id]]
       thread::send -async $threadID [list set wTID $threadID]

       thread::send -async $threadID {
           getSock $sock

           #WHY THIS CAUSE WINDOWS ERROR !!!!! - (Possibility the procs in threas is not there yet ??)
           #SendMessage $sock " Connected to Echo server (Handler: [thread::id] at sock $sock)"
       }
   }

   #WHY IF THE CLIENT DIES, THE SERVER ALSO DIES !!!!!!
   puts "Server waiting for connections at port $port..."
   vwait forever



and this is a simple client to connect to it :



Code:
proc read_sock {sock} {
 set l [gets $sock]
 puts stdout "ServerReply:$l"
}

proc read_stdin {wsock} {
 global  eventLoop
 set l [gets stdin]
 if {[eof stdin]} {
   close $wsock             ;# close the socket client connection
   set eventLoop "done"     ;# terminate the vwait (eventloop)
 } else {
   puts $wsock $l           ;# send the data to the server
 }
}

set eshost "localhost"
set esport 9001

set esvrSock [socket $eshost $esport]

fileevent $esvrSock readable [list read_sock $esvrSock]

fconfigure $esvrSock -buffering line -blocking 0

fileevent stdin readable [list read_stdin $esvrSock]

puts "EchoServerClient Connected to echo server $esvrSock"

#vwait eventLoop
vwait forever

puts "Client Finished"



For info, i use a TCL 8.4.9 thread-enable core and Thread 2.6 package for the testing ...

Really need some help here ...

Thank you
mawardi

Posted by admin (Graham Ellis), 2 June 2005
Hi, welcome, Mawardi

I've done some threading in Java and Python but I'm not all that familiar with it in Tcl - so the best I can offer you straight off are some clues / thoughts.

My first thought is that threads are HIGHLY OS dependent ... they tend to work well on Linux and most versions of Unix, perhaps not so well on some of the more exotic versions of Unix and they can be poor or broken on Windows boxes.   I don't see what OS you're using - although one of your comments refers to "Windows".

What OS are you using?  If Windows, have you tried running your code on a Linux system?   The first thing I would do in your shoes is to try another platform to see if I was experienceing some artefact of the OS, or whether I had a hard bug.



Posted by mawardi (mawardi), 2 June 2005
Thanks for the reply...

Im using Windows XP ...

I will try it on the a Linux system and see how it goes ..

Thanks
mawardi

Posted by mawardi (mawardi), 14 June 2005
Just an update ...

On linux, TCL 8.4.9 & Thread 2.6.1 work fine  

But recently they released TCL 8.4.10 and fix some bugs for channel handling for Threads ... which what i suspected caused the error ....

So now Windows can use tcl threads, only if the core is 8.4.10 and you want to use channel handling (thread::attach, detach, transfer) ...



This page is a thread posted to the opentalk forum at www.opentalk.org.uk and archived here for reference. To jump to the archive index please follow this link.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2024: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho