Python中如何在一段时间后停止程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python中如何在一段时间后停止程序相关的知识,希望对你有一定的参考价值。
写了一个分析大数据的python程序,由于要分析的数据量可能会很大,有时运行的时间会很长。服务器上的设置是有进程运行超过10分钟会自动Kill该进程,所以我希望我的程序在运行到9分50秒的时候可以Print一条警报“Warning: Timeout”。
请问需要如何修改程序才能达到此目的,能否只在程序头尾添加语句而不改变程序内部结构?
以下面一个无线循环的Loop为例,如何修改能让它在10秒后打印一条警报?
def func(a,b):
while True:
a=a+b
print a
func(1,2)
用到threading的Timer,也类似单片机那样子,在中断程序中再重置定时器,设置中断,python实例代码如下:
import threading
import time
def change_user():
print('这是中断,切换账号')
t = threading.Timer(3, change_user)
t.start()
#每过3秒切换一次账号
t = threading.Timer(3, change_user)
t.start()
while True:
print('我在爬数据')
time.sleep(1)
扩展资料
有时当一个条件成立的情况下,需要终止程序,可以使用sys.exit()退出程序。sys.exit()会引发一个异常:
1、如果这个异常没有被捕获,那么python编译器将会退出,后面的程序将不会执行。
2、如果这个异常被捕获(try...except...finally),捕获这个异常可以做一些额外的清理工作,后面的程序还会继续执行。
注:0为正常退出,其他数值(1-127)为不正常,可抛异常事件供捕获。另一种终止程序的方法os._exit()
一般情况下使用sys.exit()即可,一般在fork出来的子进程中使用os._exit()
采用sys.exit(0)正常终止程序,程序终止后shell运行不受影响。
采用os._exit(0)关闭整个shell,调用sys._exit(0)后整个shell都重启了(RESTART Shell)。
参考技术A #python 2.7import time #导入 time类
start=time.clock()
def func(a,b):
while True:
end=time.clock ()
if int(end-start)==10:
print('Warning: Timeout!!'*5)
break
a=a+b
print a
func(1,2)
主要思路:开始时间-当前时间=10则停止运行并输出时间到了(注意缩进)追问
多谢。方法是很简洁,但是有一个小问题啊。
我给的这个例子里func的功能很简单,只有a=a+b这样简单的计算。如果function里的计算量会很大。如果只在循环开头判定时间的话,如果在某次循环内就达到时间上线的话,来不及进行下一次循环判定时间就会被服务器Kill了,这样会答应不了警报信息哦。请问有没有办法实时监控时间呢?比如每秒判定一次时间,类似于独立于主程序之外再创建一个监控时间的进程。有办法实现吗。。。
你说的我考虑过,但是情况都一样的,怎么样都要消耗资源,只要你去计算时间。
有比较好的方法就是:再建立一个进程,单独的在主程序运行时他运行,然后他只做计时,10秒后在print。但这样的方法比较复杂。
另外:如果从解决问题角度出发的话,有很多的办法啊,可以同时执行2个程序,一个是主程序,一个是只做计时等待警告程序,可以用批处理。
python warn.py
python main.py
做成bat就行了。相对而言等待程序消耗资源很少。也可以直接用批处理去等待,效率更高
使用前先做一个简单试验:
import threading def sayhello():
print "hello world"
global t #Notice: use global variable!
t = threading.Timer(5.0, sayhello)
t.start()
t = threading.Timer(5.0, sayhello)
t.start()
运行结果如下
>python hello.py
hello world
hello world
hello world
下面是定时器类的实现:
class Timer(threading.Thread): """
very simple but useless timer.
"""
def __init__(self, seconds):
self.runTime = seconds
threading.Thread.__init__(self)
def run(self):
time.sleep(self.runTime)
print "Buzzzz!! Time's up!"
class CountDownTimer(Timer):
"""
a timer that can counts down the seconds.
"""
def run(self):
counter = self.runTime
for sec in range(self.runTime):
print counter
time.sleep(1.0)
counter -= 1
print "Done"
class CountDownExec(CountDownTimer):
"""
a timer that execute an action at the end of the timer run.
"""
def __init__(self, seconds, action, args=[]):
self.args = args
self.action = action
CountDownTimer.__init__(self, seconds)
def run(self):
CountDownTimer.run(self)
self.action(self.args)
def myAction(args=[]):
print "Performing my action with args:"
print args
if __name__ == "__main__": t = CountDownExec(3, myAction, ["hello", "world"])
t.start()追问
请问我的那段代码应该放在什么位置?我对编程还是门外汉。。。。
参考技术C 把程序单开成一个线程或者进程,最好开进程,python的多线程。。。不太好用,然后用time模块等待几秒,之后直接结束进程就行。 参考技术D 用装饰器能做到。不过有点技巧为啥 Loki 的 Docker 驱动程序客户端在一段时间后停止登录?
【中文标题】为啥 Loki 的 Docker 驱动程序客户端在一段时间后停止登录?【英文标题】:Why is Loki's Docker Driver Client stopping to log after some time?为什么 Loki 的 Docker 驱动程序客户端在一段时间后停止登录? 【发布时间】:2021-04-27 16:11:32 【问题描述】:我想将我的 Docker 容器的日志发送到 Grafana Loki。因此,我安装了 Loki 的 Docker Driver Client 并用它启动了我的容器。一开始我可以看到日志,但一段时间后我看不到更多日志。
安装
我在我的 Docker 引擎(版本 20.10.2)上以 Docker plugin 的形式安装了 Loki 的 Docker 驱动程序客户端:
$ docker plugin install grafana/loki-docker-driver:master-54d1d3b --alias loki --grant-all-permissions
我没有使用标签lastest
,因为错误Unable to connect to logging plugin in Swarm
配置
我使用 Loki 的 Docker Driver Client 作为日志驱动程序启动了我的 Docker 容器:
$ docker container run
--log-driver=loki
--log-opt loki-url="$LOKI_URL"
--log-opt loki-retries=5
--log-opt loki-batch-size=400
--log-opt max-size="10m"
--log-opt max-file=5
--detach
--name $CONTAINER_NAME
--restart unless-stopped
$IMAGE:$TAG
我还添加了json-log驱动的max-size
和max-file
来限制磁盘空间,见Configuring the Docker Driver。
问题
首先我可以在Grafana 和docker container logs
的命令行中看到日志,但一段时间后不再显示日志。如果我尝试查看 Docker 主机上的日志并看到错误:
$ docker container logs 75d4b13eb3e8
error from daemon in stream: Error grabbing logs: error getting log reader: LogDriver.ReadLogs: logger does not exist for 75d4b13eb3e8203b9247ecdeb41fdf495cc8fea7dcfc4775fd8261263b1dcd32
研究
我查看了容器的目录(请参阅Where is a log file with logs from a container?),但看不到任何日志文件:
$ sudo ls /var/lib/docker/containers/75d4b13eb3e8203b9247ecdeb41fdf495cc8fea7dcfc4775fd8261263b1dcd32
checkpoints config.v2.json hostconfig.json hostname hosts mounts resolv.conf resolv.conf.hash
我也检查了日志路径(见Get an instance’s log path),但它是空的:
$ docker inspect --format='.LogPath' 75d4b13eb3e8
我在插件目录中找到了容器的日志(参见Loki log driver not storing logs as files on disk, even with keep-file: true),但日志文件不再更改:
$ sudo ls -la /var/lib/docker/plugins/eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288/rootfs/var/log/docker/75d4b13eb3e8203b9247ecdeb41fdf495cc8fea7dcfc4775fd8261263b1dcd32
total 912
drwxr-xr-x 2 root root 4096 Jan 22 12:59 .
drwxr-xr-x 17 root root 4096 Jan 22 15:46 ..
-rw-r----- 1 root root 923177 Jan 22 13:34 json.log
我查看了 Docker 守护程序的日志(请参阅 Read the logs)并发现错误和警告(同时记录停止):
$ sudo journalctl -u docker.service | grep eac33cc9913c
[...]
[...]level=error msg="panic: send on closed channel" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="goroutine 153 [running]:" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="main.(*loki).Log(0xc0000c5e00, 0xc0001d81c0, 0xc0000c5e80, 0x0)" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="\t/src/loki/cmd/docker-driver/loki.go:69 +0x2fb" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="main.consumeLog(0xc0002c0480)" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="\t/src/loki/cmd/docker-driver/driver.go:165 +0x4c2" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="created by main.(*driver).StartLogging" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=error msg="\t/src/loki/cmd/docker-driver/driver.go:116 +0xa75" plugin=eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288
[...]level=warning msg="Unable to connect to plugin: /run/docker/plugins/eac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288/loki.sock/LogDriver.StopLogging: Post http://%2Frun%2Fdocker%2Fplugins%2Feac33cc9913ca962a189904392e516dd495d6fd52391fb5af4a34af46b281288%2Floki.sock/LogDriver.StopLogging: EOF, retrying in 1s"
[...]
我做错了什么?
【问题讨论】:
【参考方案1】:我遇到了同样的问题。
我在配置上的唯一区别是我正在试用最新的企业版 (19.03),因为它带来了dual logging capability,尽管最新的 CE 版本也支持这一点,而且我现在使用的是最新的 Loki Docker 驱动程序客户端前面提到的 Github 问题已经解决。
我最终在 docker-compose.yml 中设置了 log-opts properties no-file
和 keep-file
:
logging:
driver: "loki"
options:
loki-url: "http://$LOKI_URL:3100/loki/api/v1/push"
loki-batch-size: "400"
no-file: "false"
keep-file: "true"
max-size: "5m"
max-file: "3"
自从进行此更改后,我在 Loki 中收到了日志,并且仍然可以在我的 Docker 主机上使用 docker 容器日志和 docker 服务日志。
no-file: "false"
告诉驱动程序继续在磁盘上创建日志,keep-file: "true"
告诉驱动程序在容器停止时保留 json 日志(默认情况下会删除文件)。
注意:最初我将这些设置添加到主机上的 /etc/docker/daemon.json 但仍然会看到 error getting log reader
问题,我不得不切换到为每个容器/群服务指定日志驱动程序。
【讨论】:
no-file: "false"
是默认值,所以我也在使用它。我没有设置keep-file: "true"
。我会试试看。但是我还必须使用max-file
来清理日志文件。【参考方案2】:
关于这个问题
首先我可以在 Grafana 和命令行中使用 docker 容器日志查看日志,但一段时间后不再显示日志。
在 Grafana 上,请选择 Query type: Range 而不是 Instant,您将看到所选时间段内的所有日志(如果存在)在洛基。
【讨论】:
使用Grafana不是问题。 Loki 中没有日志了。以上是关于Python中如何在一段时间后停止程序的主要内容,如果未能解决你的问题,请参考以下文章
如何在一段时间后或每次我对文件进行更改时停止 npm start?
为啥 Loki 的 Docker 驱动程序客户端在一段时间后停止登录?