线程无法获取队列中的项目

时间:2016-07-07 09:08:15

标签: python multithreading queue

有两个相关的文件: backend_service.py和web_handler.py

backend_service.py中的

job_queue = Queue.Queue(5)

def submit_job(job):

    job_queue.put(job)
    logger.info("Enqueue new Job: JobID:%d,queue size:%d" %(job.order_id,job_queue.qsize()))

def handle_photos():
     while True:
       if not job_queue.empty():

            job = job_queue.get_nowait()
            logger.info("---------got job:%d" %job.order_id)

            print "======================I am a task================"
            job_queue.task_done()

        else:
            logger.info("the queue is empty. will sleep 20 seconds:%d..." %job_queue.qsize())

            time.sleep(20)

worker_thread = threading.Thread(target=handle_photos)
worker_thread.setDaemon(True)
worker_thread.start()
web_handler.py中的

(基于web.py的web应用程序来处理http请求.Web服务器是uwsgi)

def GET():
    job = Job()
    backend_service.submit_job(job) 

将被调用,job_queue.qsize可以在submit_job函数中返回正确的值。但是线程总是说队列是空的。

看起来线程无法在Web服务状态下获得Queue的正确状态。虽然我使用单元测试来测试逻辑。它可以正常工作。 你能帮我看看我错了吗?

2 个答案:

答案 0 :(得分:0)

我认为您的问题是您的脚本在线程有机会从队列中收集任何项目之前完成。

backend_service.py中,在将任何内容添加到队列之前启动您的线程,因此您得到"队列为空..." ,第一个时间。

web-handler.py中,我认为发生了什么(虽然我无法确定没有更多代码),但是导入backend_service启动线程和队列,你调用{{1然后脚本结束,也在它有机会再次查看队列之前结束线程。

如果在job_submit调用后添加延迟,您将看到submit_job()成功从队列中取出项目。我已将您的代码编辑为MCVE,包括提交作业后的延迟(并且只在循环之间休眠2秒),一切正常:

backend_service.py:

handle_photos()

web_handler.py:

import Queue
import threading
import time

job_queue = Queue.Queue(5)

def submit_job(job):

    job_queue.put(job)
    print("Enqueue new Job: JobID:%d,queue size:%d" %(job.order_id,job_queue.qsize()))

def handle_photos():
    while True:
        if not job_queue.empty():

            job = job_queue.get_nowait()
            print("---------got job:%d" %job.order_id)

            print "======================I am a task================"
            job_queue.task_done()
        else:
            print("the queue is empty. will sleep 20 seconds:%d..." %job_queue.qsize())

            time.sleep(2)

worker_thread = threading.Thread(target=handle_photos)
worker_thread.setDaemon(True)
worker_thread.start()

输出:

import backend_service
import time

class a():
    def __init__(self,order_id):
        self.order_id = order_id

for i in range(3):
    job = a(i)
    backend_service.submit_job(job)

time.sleep(20)

答案 1 :(得分:0)

这是由于新的消费者线程与生产者线程不在同一个过程中。

我不确定根本原因,也许是因为uwsgi?