先说说我自己要实现的睡眠机制逻辑吧
import cv2
import os
models_path = "target/"
models = os.listdir(models_path)
index = len(models) - 1
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
net = cv.dnn.readNetFromTorch(models + styles[index])
cv2.imshow("style", frame)
就是没间隔等长的时间,让index的索引加一,我之所以一开是没有解决这个问题,是我一直想用取余的数的方式去判断这个时间间隔,但是由于while在一直不停的循环,就会导致在到了那个时间节点的时候同时被加啦好几次,所以就一直没有实现这个机制,所以在面对while循环的时候,不要采用取余数的方式进行定时任务,不然你会踩很多坑
好吧,下面进入正题吧
一、time模块实现定时任务
1、 睡眠机制
time实现定时任务主要是通过睡眠机制来实现的,一般的睡眠机制是这样的:
import time
def time_interval():
print("hello world")
time.sleep(3)
if __name__ == "__main__":
time_interval()
然后用time的睡眠机制加载到我自己的逻辑中
import cv2
import os
import time
models_path = "target/"
models = os.listdir(models_path)
tmp = len(models)
cap = cv2.VideoCapture(0)
index = 0
def time_interval():
global index
time.sleep(3)
index += 1
if index == tmp - 1:
index = 0
while True:
ret, frame = cap.read()
time_interval()
net = cv.dnn.readNetFromTorch(models + styles[index])
cv2.imshow("style", frame)
这种方法会存在两个问题:
- 1、当的睡眠的时候,
cv2.imshow("style", frame)
就会停止执行,画面就会就会停滞。 - 2、睡眠函数会被一直调用
2、取余数的方式
import os
import time
models_path = "target/"
models = os.listdir(models_path)
tmp = len(models)
cap = cv2.VideoCapture(0)
index = 0
while True:
ret, frame = cap.read()
time_interval()
start = int(time.time())
if start % 3 == 0:
index += 1
if index == tmp:
index = 0
net = cv.dnn.readNetFromTorch(models + styles[index])
cv2.imshow("style", frame)
这种方式会导致到三的倍数的时候,由于取整和while不停的刷新,例如3.1 222 和3.3344取整都是三,都是三的倍数,就会导致在这个临近的时间点被多次加一,逻辑实现失败!!!
二、datetime模块实现睡眠机制
datetime的实现截止和time模块差不多,这里不做介绍了
三、用threading 线程模块实现定制任务
threading可以实现定时的任务分发的任务,所以所考虑通过这种方实现一个每隔相等时间间隔之后进行加一的操作。
1、 threading实现基本线程定时
from threading import Timer
def fun():
print("hello, world")
if __name__=='__main__':
t = Timer(5.0, fun)
t.start() # 5秒后, "hello, world"将被打印
或者
def fun():
print "Hello World"
t = Timer(2, fun)
t.start()
if __name__ == "__main__":
fun()
或者用Thread类
from threading import Timer
import time
def fun():
print("hello, world")
time.sleep(3)
if __name__=='__main__':
t = Thread(target=fun)
t.start() # 5秒后, "hello, world"将被打印
但是这种方法也是会出现一个问题,就是到时间节点之后出现被多次加一的操作,应用到逻辑中的代码我就不列出了
四、用schedule模块实现定时任务
我最终是用schedule模块解决的这个定时任务的
,我分析了我之前都没有解决这个问题,一方面是我有的地方时使用了取余的方式,还有就是while不断循环。下面来介绍schedule模块的详细使用
schedule
:是一个轻量级的定时任务调度的库。他可以完成每秒钟,每分钟,每小时,每天,周几,特定日期的定时任务。因此十分方便我们执行一些轻量级的定时任务。
使用主要分成三个步骤:
- 1、定义定时任务
- 2、用schedule模块绑定定时任务
- 3、在循环中运行绑定的定时任务
代码如下:
```python
import schedule
import time
def job():
print("I'm working...")
schedule.every(2).seconds.do(job)
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).days.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
while True:
schedule.run_pending()
time.sleep(1)
上面的意思就是:
每隔l两秒钟执行一次任务
每隔十分钟执行一次任务
每隔一小时执行一次任务
每天的10:30执行一次任务
每隔5到10天执行一次任务
每周一的这个时候执行一次任务
每周三13:15执行一次任务
`run_pending:运行所有可以运行的任务`
***
*当然,如果函数中带有参数怎么办呢?*
很简单,如下所示:
```python
import schedule
import time
def job(name):
print("her name is : ", name)
name = xiaona
schedule.every(10).minutes.do(job, name)
schedule.every().hour.do(job, name)
schedule.every().day.at("10:30").do(job, name)
schedule.every(5).to(10).days.do(job, name)
schedule.every().monday.do(job, name)
schedule.every().wednesday.at("13:15").do(job, name)
while True:
schedule.run_pending()
time.sleep(1)
应用在我自己的逻辑中:
import cv2 as cv
import schedule
index = 0
def time_interval():
global index
time.sleep(3)
index += 1
if index == tmp - 1:
index = 0
schedule.every(2).seconds.do(interval)
while True:
schedule.run_pending()
ret, frame = cap.read()
net = cv.dnn.readNetFromTorch(models + styles[index])
cv2.imshow("style", frame)
还是schedule模块好用!!!
还有一个叫sched
任务的调度模块,这里就不说了,可以参考这里