如何将循环转换为不阻塞 Tcl 事件循环?

问题描述 投票:0回答:0

我正在编写一个 TCL/Tk 应用程序,它在某个时候有一个最终运行以下循环的按钮:

    while {[llength $Queue]>0} {
        thread::mutex lock [tsv::set Workers Mutex]
        while {[tsv::llength Workers Available]==0} {
            thread::cond wait [tsv::set Workers Notify] [tsv::set Workers Mutex]
        }
        set tid [tsv::lpop Workers Available 0]
        thread::mutex unlock [tsv::set Workers Mutex]

        set Queue [lassign $Queue item]

        thread::send -async $tid "threaded_item $item"
        
        while {[tsv::llength Result Items]} {
            display_result {*}[tsv::lpop Result Items]
            update
        }
    }

    for {set i 0} {$i<$ThreadCount} {incr i} {
        thread::mutex lock [tsv::set Workers Mutex]
        while {![tsv::llength Workers Available]} {
            thread::cond wait [tsv::set Workers Notify] [tsv::set Workers Mutex]
        }
        set tid [tsv::lpop Workers Available 0]
        thread::mutex unlock [tsv::set Workers Mutex]
        thread::release $tid

        while {[tsv::llength Result Items]} {
            display_result {*}[tsv::lpop Result Items]
        }
    }

threaded_item
将运行冗长的事情,并将结果附加到
Result Items
TSV(线程共享变量)中,将自身重新添加到
Workers Available
TSV 中,并发送有关存储在
Workers Notify
TSV 中的条件句柄的通知。
Queue
将整个工作负载分成多个份额,第一个循环将这些份额分配给线程,第二个循环耗尽最后分配给每个线程的工作结果并释放它们。

这样我就可以并行化工作负载,原则上它是可行的。问题是循环阻塞了应用程序。我想是因为它是用pthreads-style notification写的,没有考虑TCL的event loop。我认为阻塞的地方是

thread::cond wait
.

在尝试解决这个问题时,我发现了一篇文章更新被认为是有害的。在我的例子中,

update
绝对是在
display_result
完成后出现在屏幕上的更新结果的 hack,它的外观看起来像是没有考虑事件循环的糟糕设计的真实例子。

所以,我想将来自线程的通知与事件循环结合起来。我希望能够暂停/重新启动或中断并停止该过程,以及添加的其他内容。问题是,该怎么做?我应该在“空闲后”运行一些东西吗?如果是的话,那会是什么?如何处理来自线程完成共享的通知?当队列耗尽需要释放线程时,如何处理最后一块?如何防止流程重复启动,以便在调度新作业之前清理已经运行的作业?最好看一个示例/教程,了解如何使用 TCL/Tk 以事件循环友好的方式重写这样的过程。

multithreading tcl event-loop
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.