PURPOSE: Describe the operation of the Tcl [event] loop. ---- Tcl/Tk's [event-oriented programming] is essentially single threaded. There is a main event loop (''Tcl_DoOneEvent'') that checks for work to do and handles that work by making callbacks. These callbacks are registered with the event loop by the [after], [fileevent] and [bind] commands, by ''-command'', ''-xscrollcommand'', and similar options on widgets, and by various things within C code. === Main Event ----+----> Callback from [Tcl_DoWhenIdle] (after idle) Loop | +----> Callback from [Tcl_CreateTimerHandler] (after N) | +----> Callback from [Tcl_CreateChannelHandler] (fileevent) | +----> Callback from [Tk_CreateEventHandler] | (bind, -command, etc) | +----> Other callbacks ([Tk_CreateGenericHandler], [Tk_CreateErrorHandler], etc.) === The natural flow of the event loop is something like: Start | |<----------------------------------------------------------+ v ^ Do I have No[*] Calculate how Sleep for at | work to do? -----> long I may sleep -----> most that much --->| | time | | Yes | | | v | Do one callback | | | +-----------------------------------------------------------+ [*] This may cause a return from the event loop if it was invoked recursively (see below) multithreading because they cause more events to be processed. ''It is just an Commands like [update], [tkwait], and [vwait] give the illusion of multithreading because they cause more events to be processed. ''It is just an illusion.'' What they really do is to invoke the event loop recursively: event ---> Callback ---> update ---> event ---> callbacks Main Main More loop loop as needed [update]: Enters the event loop and services both queues in the normal manner until all events remaining in the main queue are scheduled in the future and the idle queue is empty. * [update] simply does the calls until there are no more to do. * [update idletasks] does only [after idle] and [Tcl_DoWhenIdle] callbacks. * [vwait] runs the event loop, including going to sleep, until some code breaks it by assigning to the specified variable. * [tkwait] has various more complex termination conditions. You need to be careful with these calls, or you can get bizarre results because your recursive call into the event loop has resulted in having the event loop make a recursive call to you. If you get into this kind of trouble, consider avoiding the four calls above and structuring your code to be callback-driven. This restructuring can be a tremendous cleaning of the stables; it's much better to structure callback-driven code from the very beginning. See [Update considered harmful] for some pointers on ways to do this. Also, as of Tcl 8.6 the [coroutine] mechanism can be a great help in this, as it can reduce your need to restructure your code. [Coroutine-enabled event handling] shows how to get the appearance of e.g. a nested [vwait] without actually doing one. [garynkill]: Hi i very new to Tcl/Tk. I need to do a simulation and wondering how to do i create multi-threading environment - as i have a skim through the [garynkill]: Hi i very new to Tcl/Tk. I need to do a simulation and wondering how to do i create multi-threading environment - as i have a skim through the "man" pages and discover there weren't any threads commands. And found out about events. How to do i go about coding where i need a timer running and after every 10s call a "command" to be run? - [RS]: It is possible to build Tcl with multiple [threads], and in the future this may even become standard. However, threads can make debugging much more difficult, and with the event model, it's easy to implement timers and repeated scheduled events: proc every {ms body} {eval $body; after $ms [info level 0]} every 10000 {puts "hello world"} [garynkill]: Thanks a lot for your help! Just an equiry it is possible to make use of only event and create a simulation program for example a simulation like [garynkill] Thanks a lot for your help! Just an equiry it is possible to make use of only event and create a simulation program for example a simulation like running 10 nodes each operating as one thread and sending each messages to one another. I know how to do it in threads in Java but i am still a newbie to Tcl/tk so asking whether it is possible to use events to do this or if you have any links to these related tutorials? It would be most helpful! Thanks again sounds fairly trivial. Use 'event generate' to send messages (assuming a "node" is represented as a widget) and 'bind' to have each node respond to the message. Use tcl/tk 8.5 so you can make use of the -data option of 'event generate'. '' [garynkill]: Thanks a lot :) [garynkill]Thanks a lot :) <
> [garynkill]Can somebody give me a rough example how event works within Tcl context or TK context where it can be implemented. Still had no heads over it. Thanks. Sorry a newbie context or TK context where it can be implemented. Still had no heads over it. [US] 'event generate' is a Tk command. For the purpose you mentioned above use 'after 0 ''handlerproc'''. This schedules your task for immediate execution (as soon as Tcl has nothing else to do). <
> [garynkill]:Then how about if i want a procedure to execute every 10 s like this can it be done by this command. <
> [US] after 10000 ''handlerproc'' (Take a look at [every]). [garynkill]One question: How do you stop cancel events in the events loop? [lexfiend] Using [after cancel], of course. ---- !!!!!! %| [Category Internals] |% !!!!!!