Celery定时任务在几次节拍后停止失败(opencv)
我有一个celery任务,每60秒运行一次,目的是抓取一个网络摄像头,拍一张静态图片,然后把它写入文件,以便服务器可以在网页上展示。这个拍照的过程是通过Python中的cv2库,也就是opencv来实现的。
它的代码大致是这样的:
@app.task # a task to get and save a webcam image
def getWebCamImage()
logger.debug("capturing image attempt")
c = cv2.VideoCapture(0) #returns a videocapture object
flag, frame = c.read() #grabs and decodes the next frame
cv2.imwrite('file/loc/img.jpg, frame) #writes the frame to a file
logger.debug('saved image...hopefully')
c.release() #releases the videocapture object
return 0
一开始运行得很顺利,但过了几分钟后,就会出现一些正常的错误,提示无法获取摄像头的属性,然后就停止了。而且它再也不会重新启动了!
...DEBUG/BEAT] celerytest.getwebcamimage[process]:capturing image attempt
VIDOC_QUERYMENU:Invalid argument
VIDOC_QUERYMENU:Invalid argument
VIDOC_QUERYMENU:Invalid argument
当它正常工作时就是这样的情况,只是它会一直运行下去。你觉得是什么原因导致它停止的呢?我是在一个树莓派上运行这个程序,给ARM核心分配了240MB内存,给图形分配了16MB。
我尝试过的一些解决方法:
$sudo sysctl vm.overvommit_memory=1
所以它没有抛出内存分配错误。 $sudo rmmod ucvideo $sudo modprobe ucvideo nodrop=1 timeout=5000 quirks=0x80 这样驱动程序对摄像头就更耐心了。我尝试过几种摄像头,所以这可能不是问题所在。
请帮忙提供任何建议或测试方法。这是个棘手的问题,因为它是在树莓派上运行,并且是树莓派和celery的结合。我打算试着用guvcview运行一个脚本,但我觉得用Python和opencv的方式更简单,因为安装起来更方便,而且无论如何我都想知道为什么这个方法不行!
最新消息:
通过DMESG命令发现,一个celery进程因为内存不足而被杀掉了。有没有办法解决这个问题?在任务中创建的对象是如何被销毁的?
1 个回答
这其实和Celery没有关系,而是和cv有关。
每次释放CV2.videocapture对象时,如果没有把它删除,内存就会一直被占用。在内存非常少的树莓派上,这很快就会占满所有内存,导致程序被杀掉。我是通过Linux中的top命令来查看内存使用情况的。
在更大的电脑上也会出现这种情况,但在树莓派上问题更严重。