2014-03-30 79 views
3

我对Python中的线程有问题(我承认,我是这个主题上的新手)。Python中的简单线程示例

我有对象,我想要在方法part1()(带有一些随机时间间隔)和part2()中生成数字列表 - 尽快打印所有生成的数字。

这里是我的代码:

import random 
import time 
from threading import Thread 


class GenerateRand: 
    def __init__(self): 
     self.h = [] 

    def part1(self): 
     while True: 
      r = random.choice(range(9)) 
      self.h.append(r) 
      print "Rand in list:", self.h 
      time.sleep(random.randint(1, 100)/100.0) 

    def part2(self): 
     while True: 
      if self.h: 
       print "Get:", self.h.pop() 


if __name__ == "__main__": 
    obj = GenerateRand() 
    th1 = Thread(target = obj.part1) 
    th2 = Thread(target = obj.part2) 
    th1.start() 
    th2.start() 
    th1.join() 
    th2.join() 

这工作得很好,但是从线程打印混合。这段代码好吗? 有没有更好的(“pythonic”:)方法来做到这一点?

+0

你为什么在这里使用线程? – jfs

+0

这只是一个例子。你可以展示如何做到这一点没有线程? :) – mchfrnc

+0

确定:'while True:print(random.randrange(9))' – jfs

回答

2

这是一个经典的producer-consumer问题。最好使用Queue在线程之间传递消息(您的情况下的消息是r中的随机数),以避免繁忙等待,从而消耗不必要的CPU时间。 Queue.get()允许等待下一个消息不忙。

除此之外,你的解决方案就好了。这就是你如何去实现这样的流程。我个人更喜欢子类threading.Thread而不是使用target的论点,但对于简单的情况,使用target是好的。 (more details here)。

当然,打印输出可以“混合”。不能保证输出到相同位置(stdout)的打印命令以及它们的执行顺序。毕竟,他们是不同的线程...

2

如果你想避免你的文本输出得到炒,你可以锁定添加到类

class GenerateRand: 
    def __init__(self): 
     self.h = [] 
     self.lock = threading.Lock() 

    def part1(self): 
     while True: 
      r = random.choice(range(9)) 
      self.lock.acquire() 
      self.h.append(r) 
      print("added: " + str(self.h)) 
      self.lock.release() 
      time.sleep(random.randint(1,100)/100.0) 
    def part2(self): 
     while True: 
      if self.h: 
       self.lock.acquire() 
       print("popped: " + str(self.h.pop())) 
       self.lock.release()