在不滞后于主进程的情况下线程更新单独的进程
Threading to update separate process while not lagging main process
抱歉,如果这很简单,我只是不知道我做错了什么。
我需要从我每 10 秒抓取一次的网站更新信息(以免网站超载)。我想使用 pygame 显示来自网站的信息。我试过使用线程模块。但是,当我让线程休眠时,它会休眠整个程序。
例如,当我做类似的事情时:
def func():
print('Hello1')
time.sleep(4)
print('Hello2')
class Display():
def __init__(self):
pg.init()
self.win = pg.display.set_mode((WIN_WIDTH,WIN_HEIGHT))
pg.display.set_caption(WIN_TITLE)
def thread_function(self):
x = threading.Thread(target = func)
x.start()
def initialize_display(self):
run = True
while run:
self.win.fill(WHITE)
self.thread_function()
for event in pg.event.get():
if event.type == pg.QUIT:
run = False
#deactivate pg library
pg.quit()
#quit program
quit()
pg.display.update()
if __name__ == "__main__":
display = Display()
display.initialize_display()
整个程序等待4.如何才能让func()的进程在4秒后才执行?
您确定要每帧开始一个新线程吗?也许只创建一次线程并在线程的目标函数内启动另一个循环,或者用另一个也能正常处理退出线程的函数包装该函数。
你可以这样做:
import pygame as pg
import threading
import time
import signal
WIN_WIDTH,WIN_HEIGHT=(400,400)
WIN_TITLE=''
WHITE='white'
def func():
print('Hello1')
time.sleep(4)
print('Hello2')
class Display():
def __init__(self):
pg.init()
self.win = pg.display.set_mode((WIN_WIDTH,WIN_HEIGHT))
pg.display.set_caption(WIN_TITLE)
def thread_function(self, should_stop):
print('[Display] starting thread')
# 'func' is wrapped in this wrapper function
# the wrapper loops until the 'should_stop'-callback returns true
def wrapper(should_stop):
print('start doing something')
while not should_stop():
func()
print('stop doing something')
x = threading.Thread(target = wrapper, args = [should_stop])
x.start()
return x
def initialize_display(self):
# run could also be an attribute of Display ....
run = True
# we keep a reference of the thread to we can wait
# for it to finish once we told it to stop
thread = self.thread_function(lambda: not run)
# when the process should be killed (e.g. CTRL+C), we also want
# to stop the thead by setting 'run' to false
def stop(sig, frame):
print('[Display] got killed, stop thread')
nonlocal run
run = False
signal.signal(signal.SIGINT, stop)
# just a little moving Rect so we see the main loops works
# fine while the thread runs in the background
r = pg.Rect((0, 200, 20, 20))
d = 1
clock = pg.time.Clock()
while run:
self.win.fill(WHITE)
for event in pg.event.get():
if event.type == pg.QUIT:
# setting 'run' to false will also stop the loop
# of the wrapper function
run = False
print('[Display] waiting for thread to finish')
# let's wait for the thread to finish
thread.join()
return
pg.draw.rect(self.win, 'dodgerblue', r)
r.move_ip(d, 0)
if not self.win.get_rect().contains(r):
d *= -1
pg.display.update()
clock.tick(60)
if __name__ == "__main__":
display = Display()
display.initialize_display()
抱歉,如果这很简单,我只是不知道我做错了什么。
我需要从我每 10 秒抓取一次的网站更新信息(以免网站超载)。我想使用 pygame 显示来自网站的信息。我试过使用线程模块。但是,当我让线程休眠时,它会休眠整个程序。
例如,当我做类似的事情时:
def func():
print('Hello1')
time.sleep(4)
print('Hello2')
class Display():
def __init__(self):
pg.init()
self.win = pg.display.set_mode((WIN_WIDTH,WIN_HEIGHT))
pg.display.set_caption(WIN_TITLE)
def thread_function(self):
x = threading.Thread(target = func)
x.start()
def initialize_display(self):
run = True
while run:
self.win.fill(WHITE)
self.thread_function()
for event in pg.event.get():
if event.type == pg.QUIT:
run = False
#deactivate pg library
pg.quit()
#quit program
quit()
pg.display.update()
if __name__ == "__main__":
display = Display()
display.initialize_display()
整个程序等待4.如何才能让func()的进程在4秒后才执行?
您确定要每帧开始一个新线程吗?也许只创建一次线程并在线程的目标函数内启动另一个循环,或者用另一个也能正常处理退出线程的函数包装该函数。
你可以这样做:
import pygame as pg
import threading
import time
import signal
WIN_WIDTH,WIN_HEIGHT=(400,400)
WIN_TITLE=''
WHITE='white'
def func():
print('Hello1')
time.sleep(4)
print('Hello2')
class Display():
def __init__(self):
pg.init()
self.win = pg.display.set_mode((WIN_WIDTH,WIN_HEIGHT))
pg.display.set_caption(WIN_TITLE)
def thread_function(self, should_stop):
print('[Display] starting thread')
# 'func' is wrapped in this wrapper function
# the wrapper loops until the 'should_stop'-callback returns true
def wrapper(should_stop):
print('start doing something')
while not should_stop():
func()
print('stop doing something')
x = threading.Thread(target = wrapper, args = [should_stop])
x.start()
return x
def initialize_display(self):
# run could also be an attribute of Display ....
run = True
# we keep a reference of the thread to we can wait
# for it to finish once we told it to stop
thread = self.thread_function(lambda: not run)
# when the process should be killed (e.g. CTRL+C), we also want
# to stop the thead by setting 'run' to false
def stop(sig, frame):
print('[Display] got killed, stop thread')
nonlocal run
run = False
signal.signal(signal.SIGINT, stop)
# just a little moving Rect so we see the main loops works
# fine while the thread runs in the background
r = pg.Rect((0, 200, 20, 20))
d = 1
clock = pg.time.Clock()
while run:
self.win.fill(WHITE)
for event in pg.event.get():
if event.type == pg.QUIT:
# setting 'run' to false will also stop the loop
# of the wrapper function
run = False
print('[Display] waiting for thread to finish')
# let's wait for the thread to finish
thread.join()
return
pg.draw.rect(self.win, 'dodgerblue', r)
r.move_ip(d, 0)
if not self.win.get_rect().contains(r):
d *= -1
pg.display.update()
clock.tick(60)
if __name__ == "__main__":
display = Display()
display.initialize_display()