放入Django多处理和空队列

时间:2014-05-23 16:00:37

标签: django multithreading queue

我试图制作类似"任务管理器"在Django中使用线程,它将等待一些工作。

import multiprocessing
from Queue import Queue


def task_maker(queue_obj):
    while True:
        try:
            print queue_obj.qsize() # << always print 0
            _data = queue_obj.get(timeout=10)
            if _data:
                _data['function'](*_data['args'], **_data['kwargs'])
        except Empty:
            pass
        except Exception as e:
            print e


tasks = Queue()
stream = multiprocessing.Process(target=task_maker, args=(tasks,))
stream.start()


def add_task(func=lambda: None, args=(), kwargs={}):
    try:
        tasks.put({
            'function': func,
            'args': args,
            'kwargs': kwargs
        })
        print tasks.qsize() # print a normal size 1,2,3,4...

    except Exception as e:
        print e

我正在使用&#34; add_task&#34;在views.py文件中,当用户发出请求时。 为什么要排队&#34; stream&#34;总是空的?我做错了什么?

2 个答案:

答案 0 :(得分:1)

当前代码存在两个问题。 1)使用多进程(但不是线程),qsize()函数是不可靠的 - 我建议不要使用它,因为它令人困惑。 2)你不能直接修改从队列中取出的对象。

考虑两个进程,来回发送数据。由于数据是私有的,人们不知道对方是否修改了一些数据。要进行通信,请使用Queue.put()或使用Pipe明确发送数据。

生产者/消费者系统的一般工作方式是:1)工作是队列中的2)工人阻塞,等待工作。当作业出现时,它会将结果放在不同的队列中。 3)管理器或“beancounter”进程使用第二个队列的输出,并打印或以其他方式处理它。

玩得开心!

#!/usr/bin/env python

import logging, multiprocessing, sys


def myproc(arg):
    return arg*2

def worker(inqueue, outqueue):
    logger = multiprocessing.get_logger()
    logger.info('start')
    while True:
        job = inqueue.get()
        logger.info('got %s', job)
        outqueue.put( myproc(job) )

def beancounter(inqueue):
    while True:
        print 'done:', inqueue.get()

def main():
    logger = multiprocessing.log_to_stderr(
            level=logging.INFO,
    )
    logger.info('setup')

    data_queue = multiprocessing.Queue()
    out_queue = multiprocessing.Queue()

    for num in range(5):
        data_queue.put(num)

    worker_p = multiprocessing.Process(
        target=worker, args=(data_queue, out_queue), 
        name='worker',
    )
    worker_p.start()

    bean_p = multiprocessing.Process(
        target=beancounter, args=(out_queue,),
        name='beancounter',
        )
    bean_p.start()

    worker_p.join()
    bean_p.join()
    logger.info('done')


if __name__=='__main__':
    main()

答案 1 :(得分:1)

得到了它。我不知道为什么,但是当我尝试&#34;线程&#34;时,它有效!

from Queue import Queue, Empty
import threading

MailLogger = logging.getLogger('mail')


class TaskMaker(threading.Thread):

    def __init__(self, que):
        threading.Thread.__init__(self)
        self.queue = que

    def run(self):
        while True:
            try:
                print "start", self.queue.qsize()
                _data = self.queue.get()
                if _data:
                    print "make"
                    _data['function'](*_data['args'], **_data['kwargs'])
            except Empty:
                pass
            except Exception as e:
                print e
                MailLogger.error(e)

tasks = Queue()
stream = TaskMaker(tasks)
stream.start()


def add_task(func=lambda: None, args=(), kwargs={}):
    global tasks
    try:
        tasks.put_nowait({
            'function': func,
            'args': args,
            'kwargs': kwargs
        })

    except Exception as e:
        print e
        MailLogger.error(e)