Подтвердить что ты не робот

Исключение Python в потоке Thread-1 (скорее всего, возникает при отключении интерпретатора)?

Мы с моим другом работали над большим проектом, чтобы учиться и веселиться в python и PyGame. В основном это симуляция AI маленькой деревни. мы хотели провести день/ночь, поэтому я нашел аккуратный способ изменить цвет всей поверхности с помощью numpy (в частности, кросс-увядающего учебника) - http://www.pygame.org/docs/tut/surfarray/SurfarrayIntro.html

Я реализовал его в коде, и он РАБОТАЕТ, но очень медленный, например < 1 fps медленно. поэтому я смотрю на threading (потому что я хотел добавить его в конце концов) и нашел эту страницу в Queues - Изучение модуля Queue в python (как его запустить)

Я трачу около 15 минут на создание базовой системы, но как только я запускаю ее, окно закрывается, и он говорит

Exception in thread Thread-1 (most likely raised during interpreter shutdown):

EDIT: это буквально все, что сказано, отсутствие ошибки Traceback

Я не знаю, что я делаю неправильно, но я полагаю, что я пропустил что-то простое. Я добавил необходимые части кода ниже.

q_in = Queue.Queue(maxsize=0)

q_out = Queue.Queue(maxsize=0)

def run():    #Here is where the main stuff happens
    #There is more here I am just showing the essential parts
    while True:
        a = abs(abs(world.degree-180)-180)/400.

        #Process world
        world.process(time_passed_seconds)

        blank_surface = pygame.Surface(SCREEN_SIZE)
        world.render(blank_surface)    #The world class renders everything onto a blank surface
        q_in.put((blank_surface, a))
        screen.blit(q_out.get(), (0,0))

def DayNight():
    while True:
        blank_surface, a = q_in.get()
        imgarray = surfarray.array3d(blank_surface)  # Here is where the new numpy       stuff starts (AKA Day/Night cycle)
        src = N.array(imgarray)
        dest = N.zeros(imgarray.shape)
        dest[:] = 20, 30, 120
        diff = (dest - src) * a
        xfade = src + diff.astype(N.int)

        surfarray.blit_array(blank_surface, xfade)
        q_out.put(blank_surface)
        q_in.task_done()

def main():
    MainT = threading.Thread(target=run)
    MainT.daemon = True
    MainT.start()

    DN = threading.Thread(target=DayNight)
    DN.daemon = True
    DN.start()

    q_in.join()
    q_out.join()

Если кто-то может помочь, это было бы очень признательно. Спасибо.

4b9b3361

Ответ 1

Это довольно часто встречается при использовании потоков демона. Почему вы устанавливаете .daemon = True в своих потоках? Думаю об этом. Хотя есть законные применения для потоков демона, в большинстве случаев программист делает это, потому что они запутались, как в "Я не знаю, как закрыть мои потоки, и программа замерзнет на выходе, если я этого не сделаю, поэтому я знаю, я скажу, что это потоки демона, тогда интерпретатор не будет ждать их завершения, когда он выйдет. Проблема решена."

Но он не решен - он обычно просто создает другие проблемы. В частности, потоки демона продолжают работать, в то время как интерпретатор - при выходе - уничтожает себя. Модули уничтожаются, stdin и stdout и stderr уничтожаются и т.д. И т.д. Всевозможные вещи могут ошибиться в потоках демонов, тогда как материал, к которому они пытаются получить доступ, аннулируется.

Конкретное сообщение, которое вы видите, создается, когда в каком-то потоке возникает исключение, но разрушение интерпретатора дошло до того, что даже модуль sys больше не содержит ничего полезного. Реализация Threading сохраняет ссылку на sys.stderr внутренне, так что она может вам что-то сказать (в частности, точное сообщение, которое вы видите), но слишком большая часть интерпретатора была уничтожена, чтобы рассказать вам что-нибудь еще о том, что пошло не так.

Итак, найдите способ отключить свои потоки чисто (и удалите .daemon = True). Не знаю достаточно о вашей проблеме, чтобы предложить конкретный способ, но вы что-нибудь придумаете; -)

Кстати, я бы предложил удалить аргументы maxsize=0 для ваших конструкторов Queue(). По умолчанию "неограничен", и "все знают это", в то время как мало кто знает, что maxsize=0 также означает "неограниченный". Это ухудшилось, поскольку другие типы данных взяли maxsize=0, чтобы означать, что "максимальный размер действительно равен 0" (лучшим примером является collections.deque); но "аргумент без аргументов неограничен" все еще универсален.