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

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

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:

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

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

  1. while contGame: #a flag to continue the game
  2. if (#conditions here)
  3. 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:

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

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

  1. while contGame: #a flag to continue the game
  2. if (#conditions here)
  3. 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。

  1. #!/usr/bin/env python3
  2. from multiprocessing import Process, Queue
  3. def announce(q):
  4. # 这作为一个独立的进程运行,等待消息并宣布它们
  5. print('[ANNOUNCER] Started')
  6. while True:
  7. # 阻塞,等待要宣布的消息
  8. message = q.get()
  9. if message is None:
  10. break
  11. print(f'[ANNOUNCER] Received: {message}')
  12. # 在这里进行你的API调用
  13. api_url = xxx
  14. response = requests.post(api_url)
  15. print('[ANNOUNCER] done')
  16. if __name__ == "__main__":
  17. # 创建一个队列以传递消息给宣布者进程
  18. q = Queue(8)
  19. print('[MAIN] Started')
  20. # 创建并启动宣布者进程
  21. announcer = Process(target=announce, args=(q,))
  22. announcer.start()
  23. # 在这里运行你现有的主程序
  24. for _ in range(10):
  25. # 将消息放入队列以宣布
  26. q.put("message")
  27. # 告诉宣布者我们已经完成,它应该退出
  28. q.put(None)
  29. # 等待它退出
  30. announcer.join()
  31. print('[MAIN] ended')

样例输出

  1. [MAIN] Started
  2. [ANNOUNCER] Started
  3. [ANNOUNCER] Received: message
  4. [ANNOUNCER] Received: message
  5. [ANNOUNCER] Received: message
  6. [ANNOUNCER] Received: message
  7. [ANNOUNCER] Received: message
  8. [ANNOUNCER] Received: message
  9. [ANNOUNCER] Received: message
  10. [ANNOUNCER] Received: message
  11. [ANNOUNCER] Received: message
  12. [ANNOUNCER] Received: message
  13. [ANNOUNCER] done
  14. [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.

  1. #!/usr/bin/env python3
  2. from multiprocessing import Process, Queue
  3. def announce(q):
  4. # This runs as a separate process, waiting for messages and announcing them
  5. print('[ANNOUNCER] Started')
  6. while True:
  7. # Block, waiting for messages to announce
  8. message = q.get()
  9. if message is None:
  10. break
  11. print(f'[ANNOUNCER] Received: {message}')
  12. # Your API call goes here
  13. api_url = xxx
  14. response = requests.post(api_url)
  15. print('[ANNOUNCER] done')
  16. if __name__ == "__main__":
  17. # Create a queue to pass messages to announcer process
  18. q = Queue(8)
  19. print('[MAIN] Started')
  20. # Create and start announcer process
  21. announcer = Process(target=announce, args=(q,))
  22. announcer.start()
  23. # Run your existing main program here
  24. for _ in range(10):
  25. # Put a message in the queue to be announced
  26. q.put("message")
  27. # Tell announcer we are finished and it should exit
  28. q.put(None)
  29. # Wait for it to exit
  30. announcer.join()
  31. print('[MAIN] ended')

Sample Output

  1. [MAIN] Started
  2. [ANNOUNCER] Started
  3. [ANNOUNCER] Received: message
  4. [ANNOUNCER] Received: message
  5. [ANNOUNCER] Received: message
  6. [ANNOUNCER] Received: message
  7. [ANNOUNCER] Received: message
  8. [ANNOUNCER] Received: message
  9. [ANNOUNCER] Received: message
  10. [ANNOUNCER] Received: message
  11. [ANNOUNCER] Received: message
  12. [ANNOUNCER] Received: message
  13. [ANNOUNCER] done
  14. [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:

确定