【问题标题】:Tcl Thread : How to access global variables in threadTcl 线程:如何在线程中访问全局变量
【发布时间】:2015-02-20 17:48:47
【问题描述】:

我有一个名为“startMyProc {num}”的过程。我希望这个过程被两个不同的线程调用并等待两个线程完成。我尝试了给出的有效解决方案。我想访问 startMyProc 中的全局变量并调用另一个过程“startMyAnotherProc {num}”。如何做到这一点?

package require Thread


global myVar

set myVar false

set id1 [thread::create -joinable {
    source sample.tcl
    thread::wait
    }]
set id2 [thread::create -joinable {
    source sample.tcl
    thread::wait
    }]

set num 1
thread::send -async $id1 [list startMyProc $num]
set num 2
thread::send -async $id2 [list startMyProc $num]

thread::join $id1
thread::join $id2

My sample.tcl looks like this,

proc startMyProc { num } {
    global myVar
    puts $myVar
    puts "Opening $num"
    after 2000
    puts "Opening $num"
    after 2000
    puts "Opening $num"
    after 2000
    startMyAnotherProc $myVar
    return
}

proc startMyAnotherProc { num } {
    puts "Opening Another Proc: $num"
    after 2000
    puts "Opening Another Proc: $num"
    after 2000
    return
}

【问题讨论】:

    标签: multithreading tcl


    【解决方案1】:

    每个线程都有自己的完整解释器,与程序中的所有其他解释器隔离(thread 包的命令功能除外)。在所有线程中获取过程的最简单、最直接的方法是将其放入脚本文件中,然后将 source 作为线程启动脚本的一部分:

    set t1 [thread::create -joinable {
        source myProcedures.tcl
        startMyProc $num
    }]
    set t2 [thread::create -joinable {
        source myProcedures.tcl
        startMyProc $num
    }]
    

    不过你会遇到另一个问题。变量不共享。这意味着你不会得到$num。你真的应该让脚本启动,然后在最后做thread::wait。然后,您可以 thread::send 他们完成工作(并在构建脚本时正确进行替换)。

    set t1 [thread::create -joinable {
        source myProcedures.tcl
        thread::wait
    }]
    set t2 [thread::create -joinable {
        source myProcedures.tcl
        thread::wait
    }]
    thread::send -async $t1 [list startMyProc $num]
    thread::send -async $t2 [list startMyProc $num]
    

    但是,如果你真的考虑将任务发送到工作线程,你应该看看线程池(tpool)的支持; 更容易扩大规模。

    # Make the thread pool
    set pool [tpool::create -initcmd {
        source myProcedures.tcl
    }]
    
    # Sent the work into the pool as distinct jobs
    set job1 [tpool::post $pool [list startMyProc $num]]
    set job2 [tpool::post $pool [list startMyProc $num]]
    
    # Wait for all the jobs in the pool to finish
    set waitingfor [list $job1 $job2]
    while {[llength $waitingfor] > 0} {
        tpool::wait $pool $waitingfor waitingfor
    }
    
    # Get results now with tpool::get
    
    # Dispose of the pool
    tpool::release $pool
    

    【讨论】:

    • 感谢您的解决方案。它有效。我还有一个疑问。我有“startMyProc {num}”,它有很多全局变量。如何在不将它们作为参数发送的情况下访问这些变量?
    • thread shared variable 的东西可能是合适的。我没有做过很多实验。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多