Наличието на множество нишки изпълнява действия въз основа на глобална променлива

Опитвам се да накарам една нишка да промени глобална променлива и след това да накарам другите нишки да проверят тази глобална променлива и ако се промени, да извършат някакво действие. Прочетох документи за нишки на python, но всичко е много ново за мен и не съм сигурен кои са най-добрите опции за това, което се опитвам да направя, или дали това, което правя, е глупаво и има по-добър начин? Този код не променя инструкциите за цветен печат, както не бих очаквал. (Освен това, този код трябва да е в python 2.x за някои други модули, които използвам в действителния си проект.) ... може би трябва да използвам обект на опашка.

import random
import sys
import threading
import time

# Globals
output = None

class Green(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        while True:
            if output == 'green':
                print 'green'
                time.sleep(1)


class Red(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        while True:
            if output == 'red':
                print 'red'
                time.sleep(1)


class Color_Randomizer(threading.Thread):
    def __init__(self):
        global output
        threading.Thread.__init__(self)

    def run(self):
        while True:
            colors = ['red', 'green']
            output = random.choice(colors)
            time.sleep(1)


def main():

    green = Green()
    red = Red()
    color_randomizer = Color_Randomizer()

    print 'Starting green'
    green.start()
    print 'Starting red'
    red.start()
    print 'Starting color randomizer'
    color_randomizer.start()

if __name__ == "__main__":
    main()

person Michael    schedule 05.05.2015    source източник
comment
return output - защо го правиш?   -  person user2357112 supports Monica    schedule 05.05.2015
comment
Това не трябва да е там, благодаря.   -  person Michael    schedule 05.05.2015


Отговори (2)


Никога не променяте глобалната променлива output. Променливата output в ColorRandomizer.run е локална променлива, която засенчва глобалната.

Вмъкнете реда global output в горната част на функцията run на Color_Randomizer.

Премахнете оператора return output в Color_Randomizer(). Вашето time.sleep повикване в следващия ред е недостъпно. Освен това няма смисъл да се връща стойност от нишка, защото няма начин да се използва.

person Paul Cornelius    schedule 05.05.2015
comment
Това проработи, благодаря. И ще разгледам опашките въз основа на коментари на @mpolednik. - person Michael; 05.05.2015
comment
Ще подкрепя всички забележки на @mpolednik. И добавете, че трябва също да разгледате нишките на демон и да разберете проблемите, свързани с правилното изключване на програми с нишки. Във вашия пример червените и зелените нишки трябва да са демони. - person Paul Cornelius; 06.05.2015
comment
Благодаря, Пол, наистина оценявам вашата помощ. Сега чета за демоните. - person Michael; 06.05.2015

В този случай кодът е много прост и следователно много скрити проблеми не се виждат тук. Първото всъщност се вижда: използването на глобални не е най-добрият начин като цяло.

Ще се появят повече проблеми, тъй като кодът става все по-сложен. Първото е, че ако използвате по-сложна глобална структура, ще трябва да се справите с атомарността на нейните модификации.

Има смисъл да комуникирате с нишките - използването на опашка е една от възможностите. Бихте изпратили текущия цвят и отговорили нишки, които разбират как да се справят с този цвят. Това е наравно с начина, по който се справяте с комуникацията в паралелна (или едновременна в случая на Python) среда.

Представете си промяната на цвета като събитие и вашия пул от нишки като манипулатори на събития. Това добре илюстрира потока: събитието се излъчва и кандидатите отговарят. Сега, дори ако добавите повече източници на събития (генератори на цветове), няма да има проблеми с едновременния достъп до една променлива. Поддържането на реда от страна би изисквало някакъв механизъм за синхронизиране.

person mpolednik    schedule 05.05.2015