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

Go/gotk3中能否在glib.TimeoutSecondsAdd循环内部修改超时间隔?

在Go/gotk3的glib.Timeout循环中动态调整超时间隔的实现方式

直接修改已创建的glib.Timeout定时器间隔是做不到的,因为glib.TimeoutSecondsAdd生成的定时器间隔是固定的。但可以通过销毁旧定时器+创建新定时器的方式实现动态调整,完全满足你根据内存占用调整更新频率的需求,具体方案如下:

核心思路

  1. 保存定时器的源ID:调用glib.TimeoutSecondsAdd会返回一个glib.SourceHandle类型的ID,将其存在全局或闭包可访问的变量中,用于后续销毁操作。
  2. 在回调内部按条件处理:
    • 内存占用过高时:先销毁当前定时器,再创建一个间隔更长的新定时器,更新源ID变量。
    • 需要停止更新时:直接销毁定时器,回调返回false(返回false本身也会触发定时器自动停止,可结合使用)。

示例代码

import (
    "github.com/gotk3/gotk3/glib"
    // 引入你的其他依赖包
)

var timeoutHandle glib.SourceHandle

// 初始化定时器,设置初始间隔(比如1秒)
func initStatsUpdater() {
    timeoutHandle = glib.TimeoutSecondsAdd(1, updateDataRate)
}

func updateDataRate() bool {
    // 1. 获取当前内存占用(替换成你实际的内存检测逻辑)
    currentMemUsage := getCurrentMemoryUsage()

    // 2. 根据内存情况调整定时器
    const highMemThreshold = 80 // 假设内存占用超过80%为过高
    const stopMemThreshold = 95 // 超过95%停止更新

    if currentMemUsage > highMemThreshold {
        // 内存过高,销毁旧定时器,创建5秒间隔的新定时器
        glib.SourceRemove(timeoutHandle)
        timeoutHandle = glib.TimeoutSecondsAdd(5, updateDataRate)
        return true // 旧定时器已移除,返回true不影响新定时器运行
    } else if currentMemUsage > stopMemThreshold {
        // 达到停止条件,销毁定时器并返回false终止循环
        glib.SourceRemove(timeoutHandle)
        return false
    }

    // 3. 执行界面数据速率更新逻辑
    refreshDataRateUI()

    // 正常情况返回true,保持当前定时器运行
    return true
}

注意事项

  • 确保源ID变量在回调中可访问,GTK的回调均在主线程执行,无需额外处理并发锁。
  • 销毁定时器时确认ID有效,避免重复调用glib.SourceRemove引发错误。
  • 回调返回true会让当前定时器持续运行,返回false会自动销毁当前定时器,需结合手动销毁操作配合使用。

内容的提问来源于stack exchange,提问作者Hoodoo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 17:52:32