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

huangapple go评论65阅读模式
英文:

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

问题

I am developing a very simple game in Python.

In the game, when the player hits the bouncing ball, I call a function named sayThis() that sends a GET or POST to a remote API located on my computer like below:

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

And within the game code where I call the sayThis() function:

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

The code works well, but when I get to this line, the game pauses for more than a second (sometimes more) and waits for the response from the API. This is frustrating because the game freezes.

How can I fix this problem?

For example, how can I create a second thread and call (run) this thread only "when the player can hit the ball (scores a point)"?

PS: I developed my game in one file main.py.

Thank you

英文:

I am developing a very simple game in Python.

In the game, when player hits the bouncing ball, I call a function named sayThis() that sends a GET or POST to a remote API located in my computer like below:

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

And within the game code where I call the sayThis() function:

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

The code works well but when I get this line, the game pauses for more than a second (sometimes more) and waits the response from the API. This is frustrating because the game freezes.

How can I fix this problem?

For example, how can I create a second thread and call (run) this thread only "when the player can hit the ball (scores a point)?

PS: I developed my game in one file main.py.

Thank you

答案1

得分: 1

我会开始第二个进程(你甚至可以使用一个更轻量级的线程),并让它保持运行。它可以阻塞,等待消息到达,然后在它们到达时将它们说出来,然后继续等待下一个消息。主程序只需发送一条快速消息,而无需等待缓慢的同步API。

#!/usr/bin/env python3

from multiprocessing import Process, Queue

def announce(q):
    # 这作为一个独立的进程运行,等待消息并宣布它们
    print('[ANNOUNCER] Started')
    while True:
        # 阻塞,等待要宣布的消息
        message = q.get()
        if message is None:
            break

        print(f'[ANNOUNCER] Received: {message}')
        # 在这里进行你的API调用
        api_url = xxx
        response = requests.post(api_url)

    print('[ANNOUNCER] done')

if __name__ == "__main__":

    # 创建一个队列以传递消息给宣布者进程
    q = Queue(8)

    print('[MAIN] Started')

    # 创建并启动宣布者进程
    announcer = Process(target=announce, args=(q,))
    announcer.start()

    # 在这里运行你现有的主程序
    for _ in range(10):
        # 将消息放入队列以宣布
        q.put("message")

    # 告诉宣布者我们已经完成,它应该退出
    q.put(None)

    # 等待它退出
    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
英文:

I would start a second process (you may even get away with a thread which is even lighter weight) and leave it running. It can block, waiting for messages and say them when they arrive, then go back to waiting for the next. The main program then only has to send a quick message rather than wait for a slow, synchronous 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')

Sample Output

[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

huangapple
  • 本文由 发表于 2023年5月22日 21:54:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76306917.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定