幽溪左畔 发表于 2022-1-8 10:41

关于死循环的新手问题

之前写消息循环时经常是 一个 whilt(true) 不接收消息 后期发现CPU占用高 就加个sleep函数减少占用 但是如果是做图形绘制的话即便是sleep(1) 也会出现很明显的闪烁只能是while(true)才能流畅绘制
后来在研究DXhook的时候发现直接在present函数中添加自己的绘制方法就可以直接流畅绘制可dx是怎么实现的无停顿连续绘制的 总不会是把sleep的参数调的很小吧
遇到类似的需要死循环的情况的时候 又有什么比较好的解决方法避免使用sleep又可以降低CPU占用呢

侃遍天下无二人 发表于 2022-1-8 11:18

你猜猜?比如要是设定帧率为60那绘制一次sleep 1/60秒应该没问题吧,另外绘制的时候只对发生变化的部分重绘

三滑稽甲苯 发表于 2022-1-8 12:07

不全屏刷新,只刷新部分屏幕
你可以看看这个 Python 的 mwe (windows下)
from time import sleep
from queue import Queue
from os import system
from _thread import start_new_thread
import ctypes

class COORD(ctypes.Structure):
    _fields_ = [("X", ctypes.c_short), ("Y", ctypes.c_short)]
    def __init__(self, x, y):
      self.X = x
      self.Y = y
def setpos(pos) -> None:
    ctypes.windll.kernel32.SetConsoleCursorPosition(
      ctypes.windll.kernel32.GetStdHandle(-11), COORD(int(pos), pos)
    )
tasks = Queue()
def queued_print(s:str, interval:float=0.02, init_pos=) -> None:
    y, x = init_pos
    dy, dx = 0, 0
    for ch in s:
      if ch == "\n":
            dy += 1
            dx = 0
      else:
            tasks.put({'s': ch, 'pos': })
            dx += 1
      sleep(interval)
def printer():
    global board
    while True:
      data = tasks.get()
      setpos(data['pos'])
      print(data['s'], end='', flush=True)

system("cls")
start_new_thread(printer, ())
start_new_thread(queued_print, ("Threaded print 1", 0.02, ))
start_new_thread(queued_print, ("Threaded print 2", 0.02, ))
sleep(0.5)
queued_print("Queued print", 0.02, )
sleep(3)

错的是世界 发表于 2022-1-8 15:32

本帖最后由 错的是世界 于 2022-1-8 15:33 编辑

需要循环执行,你可以考虑设置一个定时器,将业务放定时器里面去执行,这样就可以灵活的制定循环周期

少年持剑 发表于 2022-1-8 15:55

跟线程调度有关,while true 如果里面没有winapi操作,那么调度只能通过时间中断来实现,会站大量的cpu时间。而图形绘制实际上进行了大量的I/O操作,GPU干活,线程处于堵塞状态的时间较多。

幽溪左畔 发表于 2022-1-12 10:44

少年持剑 发表于 2022-1-8 15:55
跟线程调度有关,while true 如果里面没有winapi操作,那么调度只能通过时间中断来实现,会站大量的cpu时间 ...

多谢刚了解这方面知识

幽溪左畔 发表于 2022-1-12 10:46

三滑稽甲苯 发表于 2022-1-8 12:07
不全屏刷新,只刷新部分屏幕
你可以看看这个 Python 的 mwe (windows下)
from...

不错的参考代码 多谢
页: [1]
查看完整版本: 关于死循环的新手问题