【问题标题】:Python class variable is None despite being set尽管已设置 Python 类变量为 None
【发布时间】:2021-10-22 13:01:28
【问题描述】:

我正在努力解决 Python 中的线程通信问题。我显然遗漏了一些东西,但我是 Python 新手,所以我不太清楚自己在做什么。

当服务器收到 GET 请求时,我希望它从单独的线程中获取两个数字(x 和 y 坐标),该线程不断更新这些值并将这些数字作为响应返回。

我有一个简单的 Django 项目,结构如下:

非常基础,按照教程制作。

当服务器启动时,我启动一个线程,看起来在一个单独的线程中启动我的坐标生成器:

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 类如下所示:

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 类只有这个方法:

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:和朋友调试了一段时间,发现好像set_coords()方法是在一个进程中调用的,而get_coords()方法是在另一个进程中调用的。

【问题讨论】:

  • 这听起来像是一个多进程问题。
  • @user2357112supportsMonica 是的。但我在 Python 方面不够熟练,无法理解这里出了什么问题。
  • @ljlozano no...所以这可能有助于从该过程中获取数据?也许有一种方法可以从我正在工作的同一进程中启动该线程?
  • 你是从 ready 方法开始的...... Django 可能会调用它两次(两个进程),请参阅 How to avoid AppConfig.ready() method running twice in Django
  • @AbdulAzizBarkat 不,这行:if os.environ.get('RUN_MAIN', None) != 'true': 确保它不会被启动两次。

标签: python django multithreading


【解决方案1】:

我建议使用您拥有的中间件实现某种 IPC。但如果它是一次性项目,您可以从某个地方的 wsgi.py 启动线程 (launch_recognition)。这将确保它在同一个进程中运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 2019-07-25
    • 2013-05-11
    • 1970-01-01
    相关资源
    最近更新 更多