微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

线程更新单独的进程而不滞后主进程

如何解决线程更新单独的进程而不滞后主进程

抱歉,如果这很简单,我只是不知道我做错了什么。

我需要从我每 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。我怎样才能让它在 4 秒后只执行 func() 进程?

解决方法

您确定要每帧开始一个新线程吗?也许只创建一次线程并在线程的目标函数内启动另一个循环,或者用另一个同样处理退出线程的函数包装该函数。

你可以这样做:

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()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。