django问题研讨:由master=true引发的奇怪现象

原实现方案

task.py设计一个类Reservation_Queue负责管理任务队列,类成员self.queue是存放任务的队列,self.nowtask是存放正在执行任务。类方法有self.addsearchtask()用于产生一个搜索任务到self.queue队列内,self.__loop()用于监视queue队列内的内容,self.main()负责启动self.__loop()的线程。

# file: task.py
class Reservation_Queue(object):
    
    def __init__(self, maxsize):
        self.queue = Queue(maxsize=maxsize)		#存放任务的队列
        self.nowtask = None						#存放正在执行的任务
        self.Lock_addtask = threading.Lock()

    def addsearchtask(self, queryset):			#产生一个任务到queue
        result = (False, 'None')
        try:
            self.Lock_addtask.acquire()
            self.queue.put(('search', queryset))
            result = (True, '已添加到任务队列!')
        except Exception as e:
            result = (False, json.dumps(e.args, indent=4))
        finally:
            print('addsearchtask', self.queue.queue, id(self.queue))
            self.Lock_addtask.release()
            return result

    def __loop(self):							#死循环监视self.queue队列里的内容
        while True:
            print(time.time(), 'task_looping...', self.queue.queue, id(self.queue))
            if not self.queue.empty() and self.nowtask is None:
                self.nowtask = self.queue.get()
                if self.nowtask[0] == 'search':
                    print('task_search')
            time.sleep(0.1)

    def main(self):								#开启self.__loop线程,实时监视队列任务。
        print('task_thread_start')
        threading.Thread(daemon=True, target=self.__loop).start()

task_reservation = Reservation_Queue(0)
task_reservation.main()

使用uwsgi部署到服务器

[uwsgi]
chdir = /www/wwwroot/ihgmiddleman/ihgmiddleman
wsgi-file = ihgmiddleman/wsgi.py
processes = 1
threads = 1
pidfile = myuwsgi.pid
master = true	#注意这个master=true,就是由它引发的血案
socket = 127.0.0.1:8003

由master=true引发的奇怪现象

先通过执行self.addsearchtask()后让self.queue任务队列产生一个任务,并且打印出来addsearchtask deque([('search', <QuerySet [<Reservation: 22247819>]>)]) 140290378282176
后面的140290378282176self.queue的地址,通过打印内容,可以看出任务已经成功的put入到self.queue里面。

!!但是奇怪的事情发生了,在self.__loop()死循环内,监视到的self.queue内容居然是空的,但是打印出来的id(self.queue)是一致的,也是地址相同140290378282176,但为什么会出现这一个奇怪的现象。

在这里插入图片描述

尝试解决问题

由于我在admin.pyviews.py开头都同时写上了from reservation.task import task_reservation,在猜想是否由于两个文件同时import,导致task_reservation指向的地址是不同的,于是我对这两个文件分别加入了print('admin.py', id(task_reservation))print('views.py', id(task_reservation))

# file: admin.py片段
...
from reservation.task import task_reservation
print('admin.py', id(task_reservation))
...
# file: views.py片段
...
from reservation.task import task_reservation
print('views.py', id(task_reservation))
...

但是事实告诉我,这样的写法是没有错误的,from reservation.task import task_reservation并不会为task_reservation重新分配一个新地址,而会直接指向task.pytask_reservation的地址:140080990537808

在这里插入图片描述

"死马当活马"解决问题

排除以上地址问题以后,我把矛头指向了uwsgi的配置文件,随手把master=true改成master=false,以上问题竟完美解决!

可以看到执行self.addsearchtask()后,跟着后面的task_looping...的队列内容也被正常的打印出来并且能输出打印task_search

在这里插入图片描述

问题与疑惑总结

这个问题就这样抱着疑惑解决了,但是为什么master=true会引发在线程内访问类成员失败,即访问self.queue的内容居然是空列表,这个让我百思不得其解。master=false之后问题竟就完美解决。
如果有知道的小伙伴,能在评论下面回答一下,解答我的疑惑吗??

猜你喜欢

转载自blog.csdn.net/csdn_xiaoyi/article/details/107661024