I'm struggling with thread communication in Python. I'm clearly missing something, but I'm new to Python so I don't know very well what I'm doing.
When the server gets a GET request, I want it to get two numbers (x and y coords) from a separate thread, which constantly updates those values and to return those numbers as a response.
I have a simple Django project with the following structure:
it is very basic, made according to tutorial.
When the server starts, I start a thread that looks launches my coordinate generator in a separate thread:
class GpsMockCoordsServiceConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'gps_mock_coords_service'
def ready(self):
if os.environ.get('RUN_MAIN', None) != 'true':
_thread.start_new_thread(CoordsTracker.launch_recognition, ())
CoordsTracker class looks like so:
coords = None
class CoordsTracker:
#coords = None #tried placin it here, but same effect - it is None when retreived from views.py
logger = logging.getLogger("CoordsTrackerLogger")
@staticmethod
def draw_contours(mask, frame, color):
......
for stuff in stuffs:
......
CoordsTracker.set_coords((x, y))
......
@staticmethod
def launch_recognition():
........
while True:
........
CoordsTracker.draw_contours(....)
........
@staticmethod
def set_coords(new_coords):
global coords
CoordsTracker.logger.debug("setting coords " str(new_coords))
coords = new_coords # here coords var is OK
@staticmethod
def get_coords():
CoordsTracker.logger.debug(coords) # Here it is OK if I call this method from draw_contours() and is not OK if I call this from views.py file.
return coords
views.py class has only this method:
def index(request):
# with CoordsTracker.coords_thread_lock:
coords = CoordsTracker.get_coords()
logger.debug("Got coords: " str(coords)) #if I do a GET request this prints 'Got coords: None'
return HttpResponse(str(coords))
UPD: after some time debugging with a friend, we found out that it appears that the set_coords() method is called in one process, while get_coords() in another process.
CodePudding user response:
I'd recommend implementing some kind of IPC with the middleware you have. But if it's a one-off project, you can just launch the thread (launch_recognition) from wsgi.py somewhere. This will ensure it all runs in the same process.