如何在Python中添加一个单独的线程以避免应用程序延迟?

How to add a separate thread in Python to avoid delays in the app?

提问人:emsiloader 提问时间:5/22/2023 最后编辑:NicPWNsemsiloader 更新时间:5/23/2023 访问量:52

问:

我正在用 Python 开发一个非常简单的游戏。

在游戏中,当玩家击中弹跳球时,我调用一个名为的函数,该函数将 GET 或 POST 发送到位于我计算机中的远程 API,如下所示:sayThis()

def sayThis(param):   
    try:
       api_url = param
       #param is here : http://localhost:54300/apistomach/say?text=great&blocking=true
       response = requests.post(api_url)
       response.json()
    except:
       print("service error occurred! check API connection ")

在我调用函数的游戏代码中:sayThis()

while contGame: #a flag to continue the game 
   if (#conditions here)
      sayThis("http://localhost:54300/apistomach/say?text=great&blocking=true")

代码运行良好,但是当我得到这一行时,游戏会暂停超过一秒钟(有时更多)并等待 API 的响应。这很令人沮丧,因为游戏冻结了。

如何解决此问题?

例如,我怎样才能创建第二个线程,并仅在“当玩家可以击球(得分)时”调用(运行)这个线程?

PS:我在一个文件中开发了我的游戏。main.py

谢谢

Python 多线程 冻结

评论

0赞 kartoffelbär 5/22/2023
我认为您正在寻找的术语是异步编程。也许可以研究一下,在你的代码中找到实现。但是,您很可能必须在击球之前执行函数调用,以便有时间访问 API。你可以让它等到它再次被异步编程调用。

答:

1赞 Mark Setchell 5/22/2023 #1

我会启动第二个过程(你甚至可以得到一个重量更轻的线程)并让它继续运行。它可以阻止,等待消息并在消息到达时说出来,然后返回等待下一个消息。然后,主程序只需要发送一条快速消息,而不是等待一个缓慢的同步 API。

#!/usr/bin/env python3

from multiprocessing import Process, Queue

def announce(q):
    # This runs as a separate process, waiting for messages and announcing them
    print('[ANNOUNCER] Started')
    while True:
        # Block, waiting for messages to announce
        message = q.get()
        if message is None:
            break

        print(f'[ANNOUNCER] Received: {message}')
        # Your API call goes here
        api_url = xxx
        response = requests.post(api_url)

  print('[ANNOUNCER] done')

if __name__ == "__main__":

    # Create a queue to pass messages to announcer process
    q = Queue(8)

    print('[MAIN] Started')

    # Create and start announcer process
    announcer = Process(target=announce, args=(q,))
    announcer.start()

    # Run your existing main program here
    for _ in range(10):
        # Put a message in the queue to be announced
        q.put("message")

    # Tell announcer we are finished and it should exit
    q.put(None)

    # Wait for it to exit
    announcer.join()
    print('[MAIN] ended')

示例输出

[MAIN] Started
[ANNOUNCER] Started
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] Received: message
[ANNOUNCER] done
[MAIN] ended