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

Python中time.sleep异常,需实现128次/秒函数执行且不影响OpenGL渲染

问题:Python实现稳定每秒128次执行的函数,同时不影响OpenGL渲染帧率

需求

需要实现一个每秒执行128次的函数,同时后台运行PyOpenGLTk的OpenGL上下文,保证渲染帧率不受影响。

初始实现代码

import time, threading

run_counter = 0

def runner():
    global run_counter

    while True:
        do_something()
        run_counter += 1
        time.sleep(1/128)

threading.Thread(target=runner).start()

执行次数统计代码

while True:
    print(run_counter)
    run_counter = 0
    time.sleep(1)

遇到的问题

  • 理论上time.sleep(1/128)能让函数每秒执行128次,但实际统计只有64次。
  • 后台运行基于PyOpenGLTk的OpenGL上下文,相关代码如下:

OpenGL画布类

class WindowGLTkCanvas(OpenGLFrame):

    def __init__(self, parent, root, size: Dimension = Dimension(100, 100), scale=1):

        OpenGLFrame.__init__(self, root, width=size.x, height=size.y)
        PynamicsObject.__init__(self, parent)
        self.parent = parent
        self.renderable = []
        self.scale = scale

        self.texture_handler = {}

        self.width = size.x
        self.height = size.y

        self.frame = Routine(self, target=self.redraw)


    def initgl(self):
        Logger.info("Call: initgl")
        glViewport(0, 0, self.width, self.height)
        glClearColor(0, 0, 0, 0)

        # 设置投影矩阵
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, self.width, self.height, 0, -1, 1)

        # 设置模型视图矩阵
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        glEnable(GL_TEXTURE_2D)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glEnable(GL_BLEND)
        #glEnable(GL_LINE_SMOOTH)

    def redraw(self):

        Logger.info("Call: draw")

        glClear(GL_COLOR_BUFFER_BIT)
        glFlush()

        #Logger.info("Call: drawend")

Tkinter包装类

class WindowGLTk():

    def __init__(self, parent):
        super().__init__(parent)

        self.root = tk.Tk()
        self.gl_canvas = WindowGLTkCanvas(self, self.root, Dim(500, 500))
        self.gl_canvas.pack(fill=tk.BOTH, expand=tk.YES)
        self.gl_canvas.animate = True

        self.parent._viewport = self

        #self.frame = Routine(self, self._tick, delay=tps_to_seconds(200))

    def _tick(self):
        print("RENDER")
        #self.gl_canvas.redraw()

    def load(self):
        self.root.mainloop()

尝试的替代方案及问题

实现轮询式睡眠函数:

def sleep(seconds: float):
    a = time.time()
    b = a + seconds
    while time.time() < b:
        pass

    return

该方案能让目标函数稳定每秒执行128次,但会导致PyOpenGLTk的redraw函数帧率远低于预期的144FPS。

自行解决的方案

采用定时批量启动任务的方式,虽显繁琐但有效:

def _loop(self):
    while True:
        for i in range(128):
            threading.Timer(i / 128, self.target).start()
        time.sleep(1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:02:22