3
from random import randrange
from time import sleep
#import thread
from threading import Thread
from Queue import Queue
'''The idea is that there is a Seeker method that would search a location
for task, I have no idea how many task there will be, could be 1 could be 100.
Each task needs to be put into a thread, does its thing and finishes. I have
stripped down a lot of what this is really suppose to do just to focus on the
correct queuing and threading aspect of the program. The locking was just
me experimenting with locking'''
class Runner(Thread):
    current_queue_size = 0
    def __init__(self, queue):
        self.queue = queue
        data = queue.get()
        self.ID = data[0]
        self.timer = data[1]
        #self.lock = data[2]
        Runner.current_queue_size += 1
        Thread.__init__(self)

    def run(self):
        #self.lock.acquire()
        print "running {ID}, will run for: {t} seconds.".format(ID = self.ID,
                                                                t = self.timer)
        print "Queue size: {s}".format(s = Runner.current_queue_size)
        sleep(self.timer)        
        Runner.current_queue_size -= 1
        print "{ID} done, terminating, ran for {t}".format(ID = self.ID,
                                                                t = self.timer)
        print "Queue size: {s}".format(s = Runner.current_queue_size)
        #self.lock.release()
        sleep(1)
        self.queue.task_done()

def seeker():
    '''Gathers data that would need to enter its own thread.
    For now it just uses a count and random numbers to assign
    both a task ID and a time for each task'''
    queue = Queue()
    queue_item = {}
    count = 1
    #lock = thread.allocate_lock()
    while (count <= 40):
        random_number = randrange(1,350)
        queue_item[count] = random_number
        print "{count} dict ID {key}: value {val}".format(count = count, key = random_number,
                                                          val = random_number)
        count += 1

    for n in queue_item:
        #queue.put((n,queue_item[n],lock))
        queue.put((n,queue_item[n])) 
        '''I assume it is OK to put a tulip in and pull it out later'''
        worker = Runner(queue)
        worker.setDaemon(True)
        worker.start()
    worker.join() 
    '''Which one of these is necessary and why? The queue object
    joining or the thread object'''

    #queue.join()    

if __name__ == '__main__':
    seeker()

我已将大部分问题放在代码本身中,但要回顾一下要点(Python2.7):

  • 我想确保以后不会为自己造成大量内存泄漏。
  • 我注意到,当我在我的 linuxbox 上的 putty 或 VNC 中以 40 的计数运行它时,我并不总是得到所有的输出,但是当我在 Windows 上使用 IDLE 和 Aptana 时,我做到了。
  • 是的,我知道队列的目的是错开你的线程,这样你就不会淹没系统的内存,但手头的任务是时间敏感的,所以无论有多少或多少,只要检测到它们就需要立即处理有; 我发现当我有队列时,我可以清楚地指示任务何时完成,而不是让垃圾收集器猜测。
  • 我仍然不知道为什么我能够在线程或队列对象上使用 .join() 。
  • 提示,技巧,一般帮助。
  • 谢谢阅读。
4

1 回答 1

0

如果我对您的理解正确,您需要一个线程来监视某些内容以查看是否有需要完成的任务。如果找到一个任务,您希望它与搜索器和其他当前正在运行的任务并行运行。

如果是这种情况,那么我认为您可能会做错事。看看 GIL 在 Python 中是如何工作的。我认为您在这里可能真正想要的是多处理。

从 pydocs 看一下这个:

CPython 实现细节:在 CPython 中,由于全局解释器锁,只有一个线程可以一次执行 Python 代码(即使某些面向性能的库可能会克服这个限制)。如果您希望您的应用程序更好地利用多核机器的计算资源,建议您使用多处理。但是,如果您想同时运行多个 I/O 密集型任务,线程仍然是一个合适的模型。

于 2013-11-06T22:37:11.910 回答