2013-08-08 7 views
0

Вот код, это фиктивные классы, которые в конечном итоге будут заменены чем-то более полезным. То, что я хочу, чтобы цикл while работал, - это вытащить данные из очереди, чтобы увидеть, была ли удалена таблетка яда. Если нет, я хочу, чтобы все, что было в инструкции else для запуска. Однако по какой-то причине он будет ждать, пока она не получает яд таблетки и только выполнить условие Разрушитель если операторПочему мой оператор python else не запускается?

class test_imports:#Test classes remove 

     def import_1(self, control_queue, thread_number): 
      print ("Import_1 number %d started") % thread_number 
      run = True 
      count = 1 
      while run == True: 
       alive = control_queue.get()     
       count = count + 1 
       if alive == 't1kill':#<==will trigger 
        print ("Killing thread type 1 number %d") % thread_number 
        run = False     
       else:#<== won't trigger 
        print ("Thread type 1 number %d run count %d") % (thread_number, count) 

При необходимости остальная часть кода:

import multiprocessing 
import time 

class test_imports:#Test classes remove 

     def import_1(self, control_queue, thread_number): 
      print ("Import_1 number %d started") % thread_number 
      run = True 
      count = 1 
      while run == True: 
       alive = control_queue.get()     
       count = count + 1 
       if alive == 't1kill': 
        print ("Killing thread type 1 number %d") % thread_number 
        run = False     
       else: 
        print ("Thread type 1 number %d run count %d") % (thread_number, count)  



     def import_2(self, control_queue, thread_number): 
      print ("Import_2 number %d started") % thread_number 
      run = True 
      count = 1 
      while run == True: 
       alive = control_queue.get()     
       count = count + 1 
       if alive == 't2kill': 
        print ("Killing thread type 2 number %d") % thread_number 
        run = False 
       else: 
        print ("Thread type 2 number %d run count %d") % (thread_number, count) 


class worker_manager: 
    def __init__(self): 
     self.children = {} 

    def generate(self, control_queue, threadName, runNum): 
     i = test_imports() 
     if threadName == 'one': 
      print ("Starting import_1 number %d") % runNum 
      p = multiprocessing.Process(target=i.import_1, args=(control_queue, runNum)) 
      self.children[threadName] = p 
      p.start()   
     elif threadName == 'two': 
      print ("Starting import_2 number %d") % runNum 
      p = multiprocessing.Process(target=i.import_2, args=(control_queue, runNum)) 
      self.children[threadName] = p 
      p.start() 
     elif threadName == 'three':  
      p = multiprocessing.Process(target=i.import_1, args=(control_queue, runNum)) 
      print ("Starting import_1 number %d") % runNum 
      p2 = multiprocessing.Process(target=i.import_2, args=(control_queue, runNum)) 
      print ("Starting import_2 number %d") % runNum 
      self.children[threadName] = p 
      self.children[threadName] = p2 
      p.start() 
      p2.start() 

     else: 
      print ("Not a valid choice choose one two or three")  

    def terminate(self, threadName): 
     self.children[threadName].join 


if __name__ == '__main__': 
    # Establish communication queues 
    control = multiprocessing.Queue() 
    manager = worker_manager() 

    runNum = int(raw_input("Enter a number: ")) 
    threadNum = int(raw_input("Enter number of threads: ")) 
    threadName = raw_input("Enter number: ") 
    thread_Count = 0 

    print ("Starting threads") 

    for i in range(threadNum): 
     manager.generate(control, threadName, i) 
     thread_Count = thread_Count + 1    

    time.sleep(runNum)#let threads do their thing 

    print ("Terminating threads")  

    for i in range(thread_Count): 
     control.put("t1kill") 
     control.put("t2kill") 

    manager.terminate(threadName) 

Пожалуйста, обратите внимание, import_2 идентичен import_1 кроме печатает что-то другое. Дело в том, чтобы доказать способность обрабатывать разные типы потоков.

+0

Что возвращает control_queue.get()? это строка? объект ? – PepperoniPizza

+0

@PepperoniPizza a string –

ответ

0

В коде вашего водителя вы control.put("t1kill").

И ваш обработчик для t1kill комплектов run = False, поэтому вы больше не возвращаетесь через цикл while run == True.

Итак, у вас нет возможности для запуска вашего else.

Если вы хотите проверить это, просто добавить, что put сек фиктивного значения:

for i in range(thread_Count): 
    control.put("dummy") 
    control.put("t1kill") 
    control.put("t2kill") 

Однако в вашем реальном кода, вы, вероятно, будете хотеть что manager.generate способа поставить некоторые полезный значения в очереди.


В качестве побочного примечания вы делаете свой код более сложным, чем это должно быть.

Во-первых, это почти всегда плохая идея написать while run == True: вместо while run:. В разделе PEP 8 Programming Recommendations говорится:

Не сравнивайте логические значения с True или False с использованием ==.

Но на самом деле, вы можете просто return как только вы сделали, и лом run флаг целиком:

while True: 
    alive = control_queue.get()     
    count = count + 1 
    if alive == 't1kill': 
     print ("Killing thread type 1 number %d") % thread_number 
     return     
    else: 
     print ("Thread type 1 number %d run count %d") % (thread_number, count) 

(Есть некоторые люди, которые скажут вам, что break, ранние return, и т. д. «плохо структурированное программирование». Но Python не является C.)

+0

Да, это было бы правдой, вот что должно произойти при условии убийства. Однако это многопоточное приложение, поэтому будет состояние удержания, когда он ничего не вытащит –

+0

@KyleSponable: Я даже не понимаю, что вы подразумеваете под этим утверждением. Код, который вы нам показывали, состоит только в том, что два '' '' '' '' '' на каждую очередь, когда-либо, и фоновые процессы ничего не делают, кроме как ждать 'get' в этой очереди, поэтому условие kill - это единственное, что вы тестируете. – abarnert

+0

@KyleSponable: Вы ожидаете, что 'get()' будет возвращать 'None' или что-то, а не блокировать? Если так ... это не то, что он делает. Вы можете передать 'block = False' (и/или передать' timeout'), и в этом случае он будет вызывать исключение 'Empty' вместо блокировки, которое вы можете обрабатывать.Но в этом случае вы определенно не хотите вращать опрос очереди как можно быстрее ... – abarnert