Python 线程无法获取队列中的项目
有两个相关文件: backend_service.py和web_handler.py 在backend_service.py中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()
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环境!