【问题标题】:Why won't my python else statement trigger?为什么我的 python else 语句不会触发?
【发布时间】:2013-08-08 01:04:46
【问题描述】:

这里是代码,这些是虚拟类,最终会被更有用的东西取代。我想要 while 循环做的是从队列中提取数据以查看是否丢弃了毒丸。如果不是,我想触发 else 语句中的任何内容。但是由于某种原因,它会等到它得到一个毒丸,并且只执行杀死条件的 if 语句

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_2import_1 相同,但打印的内容不同。重点是证明处理不同线程类型的能力。

【问题讨论】:

  • control_queue.get() 返回什么?它是一个字符串吗?一个对象?
  • @PepperoniPizza 一个字符串

标签: python if-statement logic multiprocess


【解决方案1】:

在您的驱动程序代码中,您首先control.put("t1kill")

您的t1kill 处理程序设置run = False,因此您不会再通过while run == True 循环返回。

因此,您的else 没有机会被触发。

如果你想测试它,只需添加 puts 一些虚拟值:

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。)

【讨论】:

  • 是的,那是真的,这就是在杀死条件下应该发生的事情。然而,这是一个多线程应用程序,所以会有一个保持条件,它不会拉任何东西
  • @KyleSponable:我什至不明白你所说的那句话是什么意思。您向我们展示的代码永远只在每个队列上执行两个 puts,而后台进程除了在该队列上等待 get 之外什么都不做,因此您唯一要测试的是终止条件。
  • @KyleSponable:您是否希望get() 返回None 或其他东西而不是阻塞?如果是这样……那不是它的作用。您可以传递block=False(和/或传递timeout),在这种情况下,它将引发Empty 异常而不是阻塞,您可以处理它。但在这种情况下,您绝对不想尽可能快地轮询队列……
  • 很抱歉没有看到您的第二条评论。我期待 get 轮询队列以寻找像 t1kill 之类的毒丸。如果该消息不在队列中,则执行 else。那你将如何处理投票?
  • 好的,我明白你所说的将虚拟值放入队列中。我怎样才能让它在不需要虚拟值的情况下执行?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多