2017-02-20 3 views
0

Я работаю над назначением, которое использует потоки, и я использую глобальные переменные, чтобы позаботиться о проблемах, которые у меня были (например, обменивать переменные между потоками). Я знаю, что использование глобальных переменных, как правило, обескуражено, поэтому я хотел спросить, подходит ли это глобальным переменным.Является ли использование глобальных переменных в этом многопоточном сценарии на питоне хорошей практикой?

Вот код. Вы найдете глобальные переменные, объявленные в function1() и function2().

from threading import Thread 
from time import sleep 
import random 
import Queue 


def getNextPrime(num): 
    flag = False 
    while(flag == False): 
     num = num + 1 
     flag = True 
     for i in range(2, num): 
      if num % i == 0: 
       flag = False 
       break 

    # if we get here num should equal our next prime 
    return num 


def function1(self): 
    i = 100 
    global output_buffer 
    output_buffer = Queue.Queue() 
    while True: 
     output_buffer.put("Thread 1: " + str(i)) 
     i -= 1 
     sleep(1) 


def function2(self): 
    while True: 
     global rand_num 
     rand_num = random.randrange(4, 99999) 
     output_buffer.put("Thread 2: " + str(rand_num)) 
     sleep(1) 


def function3(self): 
    while True: 
     output_buffer.put("Thread 3: " + str(rand_num/2.5)) 
     sleep(1) 


def function4(self): 
    prime_num = 1 
    for i in range(0, 20): 
     output_buffer.put("Thread 4: " + str(prime_num)) 
     prime_num = getNextPrime(prime_num) 
     sleep(1) 

# if I don't handle output like this I get weird behavior like two threads printing on the same line 
def buffer_dump(self): 
    while True: 
     while not output_buffer.empty(): 
      print output_buffer.get() 
     sleep(1) 

if __name__ == "__main__": 
    random.seed() 
    thread1 = Thread(target=function1, args=(1,)) 
    thread2 = Thread(target=function2, args=(1,)) 
    thread3 = Thread(target=function3, args=(1,)) 
    thread4 = Thread(target=function4, args=(1,)) 
    output_thread = Thread(target=buffer_dump, args=(1,)) 

    thread1.start() 
    output_thread.start() 
    sleep(2) 
    thread2.start() 
    sleep(2) 
    thread3.start() 
    sleep(2) 
    thread4.start() 

ответ

0

Вы хорошо использовали глобальные переменные. Однако ваш код может быть даже более читабельным, если вы переместите две глобальные переменные вне ваших функций. Это не повлияет на их объем. Вы можете прочитать это на глобальные переменные тоже здесь,

https://docs.python.org/2/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

+0

Только что попробовал, я получаю 'NameError: [var] not defined', когда мои потоки начинаются. Я также попытался инициализировать их в главном блоке, и он все еще не работал. – Eric

0

Ач. Я вижу проблему. Python не разрешает объявления переменных и инициализации на разных строках. Объявляем и инициализируем все переменные на той же линии, как это,

rand_num = random.randrange(4, 99999) 

и не нравится,

global rand_num 
    rand_num = random.randrange(4, 99999) 

Удалить глобальное ключевое слово из всех переменных. Затем поместите все переменные с ключевым словом global вне всех определений ваших функций.

+0

Так что я немного поиграл с ним. Я собирался избежать объявления моего выходного буфера как глобальной переменной, но не «rand_num». Что произойдет, так это назначение rand_num в функции2 не будет обновлять эту переменную, если она используется в функции3. Если бы я действительно хотел избежать глобальных переменных, я мог бы просто объявить класс Rand_num с помощью геттеров и сеттеров. Думаю, я могу это сделать. – Eric

Смежные вопросы