I am using python 2.7.14 and am currently trying to draw to 2 sides of a pygame screen simultaneously using the multiproccesing module(2 threads are calling functions from a single pygame screen) but everytime I call a function from screen(like screen.get_width()
for example) the following error is raised:
Process Process-1:
Traceback (most recent call last):
File "C:\Python27\lib\multiprocessing\process.py", line 267, in _bootstrap
self.run()
File "C:\Python27\lib\multiprocessing\process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "C:\Python27\multiplayer.py", line 9, in single_core_game
print screen.get_width()
error: display Surface quit
I know writing from threads isn't the most elegant way so I'll be glad to hear alternatives.
Thanks!
As @Fredrik comments, you probably want to use a thread, not a separate process. Threads share access to memory & variables etc., whereas separate processes have a separate copy from the point the child process was started.
So if I may re-phrase your question:
And to which the short-answer is: "You don't".
Generally, with event driven, window-based desktops, programs have a single thread that manages interaction with the user, including handling input and output to the screen. Sure you might be able to call
screen.blit(...)
from multiple threads because of the Python GIL, but it's not a good design path to be walking.But! That is not to say other threads and processes cannot create content for the display, but then hand it off to the main handler thread for that final blit to the screen, so how?
Separate python processes can communicate with each other with
Client
andListener
pipes (this gets around the GIL too), and as mentioned before, separate threads can just share memory.Here's a kludgey piece of code that renders a background image to an off-screen surface, and then posts an event to the main thread when each new update is ready. Obviously it's a trivial use of a thread, but if there was a more time-consuming update process, it would fit better.
The thread function initially creates a pygame Surface, making it look like an 8-bit rendition of the inky blackness of space. Then forever-more pans across the image, sending a copy as a Pygame.Event to the main thread via the event queue. The main thread sees this event, and updates it's background image.
The result is kind-of jerky, but this is because I put the thread to sleep for 500ms on each iteration to slow it down a bit.
Hmm, looking at the animation, it seems like I have an off-by-1 bug in the folding of space. I guess the code needs more spice.