Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 线程无法获取队列中的项目_Python_Multithreading_Queue - Fatal编程技术网

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

Python 线程无法获取队列中的项目,python,multithreading,queue,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()

有两个相关文件: 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处理http请求的web应用程序。web服务器为uwsgi)

将被调用,并且
job\u queue.qsize
可以在
submit\u job
函数中返回正确的值。然而,线程总是说队列是空的

看起来线程无法在web服务状态下获得队列的正确状态。而我使用单元测试来测试逻辑。它可以正常工作。
你能帮我查一下我哪里错了吗?

我想你的问题是,你的脚本在线程有机会从队列中收集任何项目之前就完成了

backend_service.py
中,线程在向队列添加任何内容之前启动,因此第一轮得到“队列为空…”

web handler.py
中,我想发生了什么(尽管没有更多的代码我不能确定),您导入
后端_服务
,它启动线程和队列,调用
submit_job()
,然后脚本结束,也在线程有机会再次查看队列之前结束线程

如果在作业提交呼叫后添加延迟,您将看到通过
handle\u photos()
成功地从队列中取出项目。我已将您的代码编辑到MCVE中,包括作业提交后的延迟(循环之间仅休眠2秒),一切正常:

backend_service.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()
web_handler.py:

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)
输出:

C:\TestScripts>python web_handler.py
the queue is empty. will sleep 20 seconds:0...Enqueue new Job: JobID:2,queue size:1

Enqueue new Job: JobID:2,queue size:2
Enqueue new Job: JobID:2,queue size:3
---------got job:2
======================I am a task================
---------got job:2
======================I am a task================
---------got job:2
======================I am a task================
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...

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

backend_service.py
中,线程在向队列添加任何内容之前启动,因此第一轮得到“队列为空…”

web handler.py
中,我想发生了什么(尽管没有更多的代码我不能确定),您导入
后端_服务
,它启动线程和队列,调用
submit_job()
,然后脚本结束,也在线程有机会再次查看队列之前结束线程

如果在作业提交呼叫后添加延迟,您将看到通过
handle\u photos()
成功地从队列中取出项目。我已将您的代码编辑到MCVE中,包括作业提交后的延迟(循环之间仅休眠2秒),一切正常:

backend_service.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()
web_handler.py:

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)
输出:

C:\TestScripts>python web_handler.py
the queue is empty. will sleep 20 seconds:0...Enqueue new Job: JobID:2,queue size:1

Enqueue new Job: JobID:2,queue size:2
Enqueue new Job: JobID:2,queue size:3
---------got job:2
======================I am a task================
---------got job:2
======================I am a task================
---------got job:2
======================I am a task================
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...
the queue is empty. will sleep 20 seconds:0...

这是因为新的使用者线程与生产者线程不在同一进程中


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

这是因为新的使用者线程与生产者线程不在同一进程中


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

传递到web处理程序命名空间的
作业队列
对象在哪里?这里有一个很好的例子,调用线程时需要传递队列对象@dodell,web_handler.py仅依赖于提交作业功能。在函数submit\u job本身中访问队列。传递到web\u处理程序命名空间的
job\u queue
对象在哪里?这里有一个很好的例子,调用线程时需要传递queue对象@dodell,web_handler.py仅依赖于提交作业功能。队列在函数submit_job中访问。感谢您的详细帮助SiHa。至于web_handler.py,我只是简化了它。它是一个基于web.py的web请求处理程序。当它收到HttpRequest时,它将触发submit_job函数。此时,您知道线程正在运行,只有当整个web应用程序关闭时,线程才应该结束。至于你的测试结果,我也得到了同样的结果。因此,我的问题是,正在运行的线程总是说队列为空,而submit_job函数可以获得队列的正确状态。很抱歉,该问题发生在web uswgi环境下。在像您这样的单元测试脚本中,它们工作得很好。我很困惑。希望你能找到答案。WenJ,在问题中提到web uswgi环境!谢谢你对SiHa的详细帮助。至于web_handler.py,我只是简化了它。它是一个基于web.py的web请求处理程序。当它收到HttpRequest时,它将触发submit_job函数。此时,您知道线程正在运行,只有当整个web应用程序关闭时,线程才应该结束。至于你的测试结果,我也得到了同样的结果。因此,我的问题是,正在运行的线程总是说队列为空,而submit_job函数可以获得队列的正确状态。很抱歉,该问题发生在web uswgi环境下。在像您这样的单元测试脚本中,它们工作得很好。我很困惑。希望你能找到答案。WenJ,在问题中提到web uswgi环境!