在此Coundown计时器中取消延迟命令时,是否有种族条件?

发布于 2025-02-10 06:54:11 字数 1300 浏览 2 评论 0原文

我已经实现了一个具有“重置”按钮来取消倒计时的倒计时计时器:

set LAUNCHTIME 5
set message $LAUNCHTIME
set afterId {}

proc countdown {remainingSeconds} {
    global afterId message
# **
    if {$remainingSeconds > 0} {
        set message $remainingSeconds
# **
        set afterId [after 1000 [list countdown [expr {$remainingSeconds - 1}]]]
    } else {
        set message "Takeoff!"
        .start configure -state normal
    }
}

label .message -textvariable message
button .start -text Start -command {
    .start configure -state disabled
    countdown $LAUNCHTIME
}
button .reset -text Reset -command {
    # Reset timer, message, and button.
    after cancel $afterId  ;# <- XXX: Could this cause a race condition?
    set message $LAUNCHTIME
    .start configure -state normal
}

grid .message
grid .start
grid .reset
grid anchor . center

这就是按下“启动”按钮时的外观:

“倒计时计时器的gif”

是否可能会有可能的种族条件。重置“倒计时发生时按下按钮?我担心在程序中执行双星号(**)之间的“重置”按钮时按下“重置”按钮。那时,没有计划执行的延迟命令,因此“重置”不会取消任何延迟命令。但是,在此之后,即使用户打算重置倒计时,也将安排一个新的延迟命令执行(设置afterID [after afterID [after afterID [after afterID [after Ind ...])。

I have implemented a countdown timer that has a "Reset" button for cancelling a countdown:

set LAUNCHTIME 5
set message $LAUNCHTIME
set afterId {}

proc countdown {remainingSeconds} {
    global afterId message
# **
    if {$remainingSeconds > 0} {
        set message $remainingSeconds
# **
        set afterId [after 1000 [list countdown [expr {$remainingSeconds - 1}]]]
    } else {
        set message "Takeoff!"
        .start configure -state normal
    }
}

label .message -textvariable message
button .start -text Start -command {
    .start configure -state disabled
    countdown $LAUNCHTIME
}
button .reset -text Reset -command {
    # Reset timer, message, and button.
    after cancel $afterId  ;# <- XXX: Could this cause a race condition?
    set message $LAUNCHTIME
    .start configure -state normal
}

grid .message
grid .start
grid .reset
grid anchor . center

This is what it looks like when the "Start" button is pressed:

GIF of countdown timer

Is there a possible race condition when the "Reset" button is pressed while a countdown is occurring? I am worried about the possibility that the "Reset" button is pressed while the program is executing the parts between the double asterisks (**) in the code above. At that point, there is no delayed command that is scheduled to execute, so the "Reset" does not cancel any delayed command. However, right after, a new delayed command will be scheduled to execute (set afterId [after 1000 ...]), even though the user has intended to reset the countdown.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半世晨晓 2025-02-17 06:54:11

TCL运行单线螺纹(至少在单个解释器中)。事件仅在事件循环中进行处理。这意味着您不必担心会发生一些可能会改变事物的事情,而执行代码的顺序块。

如果用户在Countdown Proc运行时单击重置按钮,则PROC一直持续到最后。当时,事件循环通过执行附加到按钮的命令选项的代码来恢复并处理按钮键。取消事件后,因此Countdown将不会再次调用。

同样,如果在事件之后的在重置按钮运行的代码运行时到期,则代码完成,请在事件开始后的的代码之前取消事件。

Tcl runs single threaded (at least within a single interpreter). Events are only handled in the event loop. That means that you don't have to worry that something happens that could change things while a sequential block of code is executed.

If the user clicks the Reset button while the countdown proc runs, the proc continues all the way to the end. At that point the event loop resumes and handles the button-click by executing the code attached to the -command option of the button. That cancels the after event, so countdown will not be called again.

Similarly, if the after event expires while the code attached to the Reset button runs, the code completes, canceling the after event before the code of the after event starts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文