如何让你的python程序,在未来某个时间去做一件事情

如何让你的程序在未来某个时间去做一件事情呢,注意,这不是简单的闹钟,简单的闹钟就像我们起床,时间设置到每天的早上7点,这是在24小时内的定时,而现在要做到更大的范围,超过24小时,扩大到月,甚至年,那么该如何做呢?
其实一旦实现了年,那么还有哪个时间不能定时呢?也许有人说,上到年,下能到毫秒吗?其实毫秒跟24小时内的定时一样,用的是datetime。

signal能搞定所有时间跨度的定时

signal是python中的一个模块,叫做信号,关于这个功能,少有人知道,因为这个涉及到系统级的编程,需要一些Linux系统编程知识。signal模块能够捕捉系统中的很多信号,比如SIGINT(ctrl+c信号,当然python也可以通过异常KeyboardInterrupt捕捉到这个信号),SIGKILL,进程被杀死的信号,比如你这个进程被别人杀死了,可以捕捉到这个信号,SIGCHLD,子进程结束的信号,比如僵尸进程结束了,父进程就可以通过捕捉这个信号知道,等等…

先说说signal的好处

python是个无所不能的语言,有人说他不能操作硬件,但是因为python能够调用c,所以python可以间接操作硬件。
但是,同样的一个功能,在python里面有好几种解决方法,哪一种是最佳,最快,最简洁的方案,那要看开发者的知识面了。
比如下面这个场景,当我们要实现一个定时"炸弹",比如在未来的某一天,让我们的程序自动的去执行某一个动作,那么就可以用signal中的闹钟——alarm功能,当然我们不会真去做一个炸弹,只是一个功能形象说明,我们可以实现,从现在开始,到明天中午12点整,打印一条语句,如果你有树莓派,可以亮一个灯,响一个蜂鸣器。
也许有人说我可以用线程threading里面的定时器timer,但是,threading里面的timer其实并不涉及的时间,它的机制是通过另开一个线程,然后在这个线程里面,需要我们自己去获取时间,设置时间,总之相比signal来说,复杂多了。
signal的功能还有很多,只不过刚才的这个场景我们会经常用到,所以在这里主要介绍它的“闹钟”功能。

编程思路

我们需要先搞清楚signal的原理,我们先通过一个小实验来了解
“每隔1秒在屏幕上打印当前时间”

最容易想到的方法

就像这样:

这个功能的实现,有很多种方法,最简单的代码如下:

import time
while 1:print(time.ctime(time.time()))time.sleep(1)

如果只想显示时分秒,代码可以这样

import time
while 1:print(time.ctime(time.time())[-13:-5])time.sleep(1)

但是,我们项目中并不是只有这一个功能,我们还有其他功能,不能把sleep函数放在主函数的while 1中。
好,那么创建一个子线程来实现,代码就像这样:

import time,threading,sys
def prinTime():while 1:print(time.ctime(time.time())[-13:-5])time.sleep(1)
p = threading.Thread(target=prinTime,args=())
p.start()
while 1:time.sleep(100)  #模拟系统做其他事情

好,很好,我们用线程实现了,而且看上去就9条语句——python就是这么简洁

采用signal

signal模块中的alarm函数,其实就是为上面这个功能而设计的,其实很多的时候,我们只需要想想:计算机发展了30多年,linux系统如此成熟,前人不是到今天才有这个功能的需要,之前肯定有发展比较成熟的方法,如果你对Linux系统编程比较熟悉,那么对你来说,首先想到的不是线程,应该是signal,因为linux系统编程中,就有这个函数。
好,该怎么做呢?
代码非常简单

  1 import time,signal2 def alarm_fun(no,frame):3     print(time.ctime(time.time()))4     signal.alarm(1)5 signal.signal(signal.SIGALRM,alarm_fun)6 signal.alarm(1)7 while 1:8    time.sleep(100)

因为我们主要是讲解signal,所以我应该把这里的每一句讲清楚(上面的线程我就不解释了)。
第1行:同时导入time,signal 两个模块
第5行:我们要使用signal这个功能,必须通过该模块中的函数singal(函数名与模块名相同),设置要捕捉哪一个信号。我们这里就是想捕捉闹钟信号,所以第一个参数就传要捕捉的信号编号——SIGALRM,这里的SIGALRM是宏定义,它的值其实是14,你也可以直接传14.第二个参数是处理这个信号的函数——alarm_fun,这个函数是我们自己定义的,函数名也是我们自己定义的,你也可以定义其他函数名。
第2行:这个函数的形式,不能随便定义,也就是它必须有两个参数,至于这两个参数名字怎么定义,是我们的事情,你可以随便,但是数量上,必须是两个参数,第一个参数就是捕捉到的信号编号,第二个参数是一个对象,在这里意义不大。
第6行:就是启动定时器,也就是触发信号,因为我们这里的实验是实现每隔1秒打印一下系统时间,所以定时是1秒,当然你可以设置其他时间。
第4行:这一行不能少,就是启动下面的闹钟,就像我们手机设置起床闹钟一样,是一次行的,还是每天的。

如何定时到,未来某个时间

刚才我们定时的1秒,如果我们要定时到明天,或者下一个月,甚至明年怎么办呢,我们如何把明年到现在的秒数计算出来?
这里就介绍一个比较简单的方法,Python其实非常强大,什么都可以实现——条条道路通罗马,看你能不能找到最快的那条!

实现思路

首先time这个模块,很多人很熟悉,它有一个time()函数能够获取到当前时间到1970的秒数。比如:

下面那个很大的数,就是从现在开始,追溯到1970年的秒数。
如果,我们能知道未来某一天到1970年的秒数就OK了,而且未来某一天我们可以任意设置。
我们继续分析time模块中的函数,有一个mktime。

mktime(…)
mktime(tuple) -> floating point number
Convert a time tuple in local time to seconds since the Epoch.
Note that mktime(gmtime(0)) will not generally return zero for most
time zones; instead the returned value will either be equal to that
of the timezone or altzone attributes on the time module.

它需要一个元组,这个元组就像这样:

我们如何得到元组呢,如果我们能够构造一个元组就好了。
但是构造元组,年月日,时分秒都好说,但是后面的星期,一年中的哪一天,是否是夏定时怎么知道呢?
经过本人的摸索,在datetime这个模块中有这个功能:
import time,datetime
print(datetime.datetime(2020,7,11,12,00,00).timetuple())
结果如下:
time.struct_time(tm_year=2020, tm_mon=7, tm_mday=11, tm_hour=12, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=193, tm_isdst=-1)
这个元组正式我们需要的,这样的话:
我们设置一个目标时间,然后转成秒数就好了,就像这样:
import time,datetime
print(datetime.datetime(2020,7,11,12,00,00).timetuple())
goal = datetime.datetime(2020,7,11,12,0,0).timetuple()
print(time.mktime(goal))
运行结果:
time.struct_time(tm_year=2020, tm_mon=7, tm_mday=11, tm_hour=12, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=193, tm_isdst=-1)
1594297830.0
因此,我们只需要把这个很大的秒数减去当前的秒数,差值给到signal.alarm()函数就行了
如果time()函数里面传一个指定日期,那么time.time(xxx)就返回那个日期到1970年的秒数。比如

  1 import signal,time,datetime2 goal = datetime.datetime(2020,7,11,12,0,0).timetuple()3 t = time.mktime(goal)4 def alarm_fun(sino,frame):5     print('主人:到时间了....')6 signal.signal(signal.SIGALRM,alarm_fun)7 signal.alarm(int(t)-int(time.time()))8 while 1:9     pass  #模拟其他时间

这样,过12个小时就会打印"主人:到时间了…",如果我们的时间定位到2021年也可以,随你了。

如何让你的python程序,在未来某个时间去做一件事情相关推荐

  1. 【编程】shell和python实现:如何做到让一个程序每1秒去做一件事情

    目录 1.实现shell编程实现 2 python编程实现 使用while循环,每隔一秒钟执行一次 sleep 1 ==>暂停1秒钟 1.实现shell编程实现 [具体]如何实现每秒钟新建一个文 ...

  2. python程序开始和结束时间

    import datetime """作者:Pgabc""" def starttime_wm_set(): global starttim ...

  3. Python程序员爬出百套美女写真集,同样是爬虫,他为何如此突出?

    相关阅读:一个90后员工猝死的全过程 前言 人生苦短,Python当歌! python爬虫 用python爬虫是一件非常使人愉快的事情,图片.数据.小视频一切皆可爬取,可是我们会经常发现下载图片的时候 ...

  4. 树莓派4B开机自启动Python程序,发送WIFI-IP至指定邮箱

    树莓派4B开机自启动Python程序,发送WIFI-IP至指定邮箱 树莓派开机自启动Python并发送IP地址到指定邮箱 环境 用Python发送邮件 获取WIFI的IP地址 整合发送邮件和获取WIF ...

  5. python程序员培训_推荐给未来Python程序员的自学路线,不再背负小白名称

    Python彻底火了之后,各种培训机构各和学校也不断加大对Python的培训力度,很多程序员学习Python都会选择去学校或公司培训.培训机构学习,但是不是每个喜欢Python编程的程序员都是可以交得 ...

  6. Python程序员Debug利器,和Print说再见 | 技术头条

    整理 | Rachel 责编 | Jane 出品 | Python大本营(id:pythonnews) [导语]程序员每日都在和 debug 相伴.新手程序员需要学习的 debug 手段复杂多样,设置 ...

  7. 为什么Python不是未来的编程语言?

    策划 | 刘燕 作者 | Rhea Moutafis 翻译 | Sambodhi 编辑 | Linda Python 现在如此火爆,已发展成为一种非常通用的语言,无论是从入门级选手到专业技术数据挖掘. ...

  8. python程序员月薪智的-在三线城市Python工程师也能拿到月薪20K

    Python是这两年编程语言绝对的霸主,你可以发现,几乎所有和程序沾边的人,都在学Python.那么,Python到底有没有用?好在哪里?适合你学吗?今天小编就来详细分析一下. 01Python究竟能 ...

  9. python程序员工作怎样-现在Python就业薪资高吗?Python程序员前景怎么样?

    现在Python就业薪资高吗?Python程序员前景怎么样? 近日,全球知名的开发者社区 Stack Overflow 发布了 2019 年度开发者调查报告.今年全球 190 个国家和地区共有近 9 ...

最新文章

  1. mysql限制小数位_Mysql中设置小数点用什么数据类型 decimal
  2. C语言实现PID算法:位置式PID和增量式PID
  3. java核心api_Java核心API之字符流使用介绍
  4. dynamic web module 2.5与2.4
  5. 利用python实现ORM
  6. 歪枣网Mysql优化总结
  7. Qt实践录:一些界面设计的记录示例
  8. EBS R12.1安装中文补丁包BUG:FAILED: file XLIFFLoader.class on worker [X]
  9. 开课吧Java课堂:什么是线程优先级?
  10. Unity AnimatorController 混合树 状态机 骨骼
  11. vue的h函数_Vue中render中的h箭头函数
  12. SQL文件导入数据库【保姆级教程】
  13. jsoup 网页抓取简介详解
  14. 解决微信开发者工具无法打开的问题
  15. Android 真实 简历
  16. MATLAB的基本用法
  17. 科技新品 | 富士胶片研发出全球最大容量数据流磁带;iGame发布内存新品“古德白”...
  18. 京东金融云发布了,这和人工智能有什么关系?
  19. 苹果怎么换行打字_2周内将你的打字速度提高3倍的方法
  20. 大华摄像头离线故障:要拔除SD卡

热门文章

  1. python 大气校正_PIE二次开发——大气校正
  2. 怎么查看域名被墙_怎么查看域名是否被墙检测(教你一招域名被墙
  3. 小程序实战 -- 仿网易蜗牛读书
  4. oracle crs 0184,CRS-0184: Cannot communicate with the CRS daemon
  5. Autojs - 打开或关闭系统代理
  6. 鲁大师性能测试要装什么软件吗,鲁大师怎么给电脑跑分?赶快看看你的电脑性能如何吧!...
  7. 分析器错误消息: 未能创建类型
  8. linux 网卡 mac 配置文件,Linux下更改网卡的MAC物理地址
  9. 复变函数与积分变换系列(一) - 复变函数与解析函数
  10. 太吾绘卷第一世攻略_太吾绘卷剑冢难度顺序排名详解 太吾绘卷剑冢怎么打/通关玩法攻略...