1

I'm trying to make multithreaded pygame app. This is example of the code

import threading
import numpy as np
import time
import sys
import pygame

class Test:
    def __init__(self):
        pygame.init()
        self.surface = pygame.display.set_mode((400, 300))

    def do_smth(self):
        while True:
            time.sleep(2)
            print(np.random.randint(10, 20))

    def test(self):
        p = 10
        while True:

            self.surface.fill((255, 255, 255))
            pygame.draw.rect(self.surface, (255, 0, 0), (p, 10, 70, 65))

            event = pygame.event.poll()

            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type == pygame.MOUSEBUTTONDOWN:
                p += 10

            pygame.display.update()

It works if I test it like

T = Test()
T.test()

But when I try to do this using threads - I get error t = threading.Thread(target=T.test) t2 = threading.Thread(target=T.do_smth)

t.start()
t2.start()

t.join()
t2.join()

Exception in thread Thread-1: Traceback (most recent call last): File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner self.run() File "/usr/lib/python3.8/threading.py", line 870, in run self._target(*self._args, **self._kwargs) File "<filename.py>", line 34, in test pygame.display.update() pygame.error: Unable to make GL context current

How can I deal with it?

Slava
  • 65
  • 4
  • Do you realy need threading for Pygame? I Think it hadels that automaticly – Passi Oct 12 '21 at 12:50
  • All graphics operations should be performed in a single thread in pygame. If you have time consuming game logic or external [database look-ups](https://stackoverflow.com/a/65877981/2280890) then those may be offloaded to a separate thread. If your graphic operations are taking too long then there are probably improvements that can be made. – import random Oct 14 '21 at 00:45

1 Answers1

1

According to the SDL FAQ (Pygame wraps SDL), you can't rely on graphics being accessible from multiple threads. You would have to transfer all your drawing to the main thread. You can still have threads running other logic.

Note that they say "main thread". It is not enough in general to use a lock. You could e.g. set up a queue with jobs to run on the main thread, and feed that queue, as long as the jobs in there can run safely in a different thread (e.g. are protected with a lock around the state they need to know what to draw).

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26