You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tcl中实现非阻塞定时任务调度 适配OpenWrt IRC bot场景

Tcl 非阻塞定时调度功能实现方案

完全适配你现有OpenWrt下Tcl 8.6的IRC bot架构,无需额外扩展包、无需多线程、不会阻塞主业务逻辑。

核心实现思路

直接使用Tcl内置after命令实现分钟级定时检查,事件驱动逻辑与你现有IRC socket处理逻辑完全兼容,无需修改原有主循环结构,没有额外依赖。

完整实现代码

1. 主脚本公共代码

把以下代码加到主脚本IRC连接初始化完成后、进入主循环之前的位置:

# 全局存储定时任务列表 结构:[list [list 时分字符串 回调命令 上次触发日期戳]]
set ::scheduled_tasks [list]

# 注册定时任务的接口
proc task-at {time_str callback} {
    # 校验HH:MM时间格式
    if {![regexp {^([01][0-9]|2[0-3]):([0-5][0-9])$} $time_str]} {
        error "时间格式错误,请使用HH:MM格式,例如12:00"
    }
    # 去重逻辑:相同时间+相同回调不重复注册
    foreach task $::scheduled_tasks {
        lassign $task exist_hm exist_callback _
        if {$exist_hm eq $time_str && $exist_callback eq $callback} {
            return
        }
    }
    lappend ::scheduled_tasks [list $time_str $callback 0]
}

# 定时任务检查触发逻辑
proc check_scheduled_tasks {} {
    set now [clock seconds]
    set current_hm [clock format $now -format "%H:%M"]
    set current_date [clock format $now -format "%Y%m%d"]

    set new_task_list [list]
    foreach task $::scheduled_tasks {
        lassign $task target_hm callback last_trigger_date
        # 时间匹配且当天未触发过则执行回调
        if {$target_hm eq $current_hm && $last_trigger_date ne $current_date} {
            # 捕获回调错误避免影响主逻辑
            if {[catch {uplevel #0 $callback} err]} {
                puts stderr "定时任务执行错误:$err"
            }
            lappend new_task_list [list $target_hm $callback $current_date]
        } else {
            lappend new_task_list $task
        }
    }
    set ::scheduled_tasks $new_task_list
    # 安排下一次检查,非阻塞
    after 60000 check_scheduled_tasks
}

# 启动定时检查器,初始化调用一次即可
check_scheduled_tasks

2. 子脚本使用示例

完全符合你要求的调用形式,直接在子脚本中注册即可:

# 指定时分添加定时任务,支持带参数的回调
task-at "12:00" procname
# 带参数写法:task-at "18:30" [list procname "参数1" "参数2"]

proc procname {optional} {
    # 指定时间要执行的业务代码,例如发送IRC频道消息
    puts $irc_sock "PRIVMSG #yourchannel :定时触发的消息内容"
}

注意事项

  • 确保你的IRC socket设置为非阻塞模式,使用fileevent处理消息接收,主循环内调用update处理所有待执行事件,即可保证定时任务和IRC消息处理互不阻塞
  • 若需要更高检查精度,可将after 60000 check_scheduled_tasks中的60000(单位毫秒,对应1分钟)调整为更小数值,例如10000对应10秒检查一次
  • 定时回调内不要执行阻塞操作(如同步大文件读写、长时间网络请求),若有此类需求可改用非阻塞IO实现

内容的提问来源于stack exchange,提问作者Hugo Simões

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:54:05