How can one Tcl thread cause an event in another?

前端 未结 2 1873
故里飘歌
故里飘歌 2021-01-21 10:01

I have a system with multiple I/O interfaces, and I\'m collecting the output of all of them into a common log. Two of the interfaces are through well-behaved channels that are

2条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-01-21 10:38

    Firstly, the main thread needs to run the event loop in order to receive events. The idiomatic way to do this is to use vwait forever once you've finished setting up your program (I assume you're not going to write to that variable) but if you are running Tk you already have an event loop (GUIs need event loops).

    There are two ways to do the messaging between threads.

    Thread events

    The thread::send command uses events to dispatch code to execute (the message) between threads. All you need to do is to tell the worker thread what the main thread's ID is so it knows where to send to. Note that you may well want to send the event asynchronously, like this:

    thread::send -async $mainID [list eventReceiver "something happened" $payload]
    

    Pipelines

    If you're using Tcl 8.6, you can use chan pipe to create an unnamed OS pipeline. You can then use normal fileevents, etc., to deliver information from thread to another that way.

    # In master
    lassign [chan pipe] readSide writeSide
    thread::transfer $worker $readSide
    thread::send $worker [list variable pipe $readSide]
    fconfigure $writeSide -blocking 0
    fileevent $writeSide readable [list handleLine $writeSide]
    
    # In worker
    fconfigure $pipe -blocking 0 -buffering line
    puts $pipe "got event: $payload"
    

    It's probably easier to use thread events in retrospect! (The main advantage of a pipe is that you can also put the worker in another process if necessary.)

提交回复
热议问题