V2EX = way to explore V2EX 是一个关于分享和探索的地方
Sign Up Now For Existing Member Sign In
推荐学习书目 Learn Python the Hard Way Python Sites PyPI - Python Package Index http://diveintopython.org/toc/index.html Pocoo 值得关注的项目 PyPy Celery Jinja2 Read the Docs gevent pyenv virtualenv Stackless Python Beautiful Soup 结巴中文分词 Green Unicorn Sentry Shovel Pyflakes pytest Python 编程 pep8 Checker Styles PEP 8 Google Python Style Guide Code Style from The Hitchhiker's Guide
This topic created in 2023 days ago, the information mentioned may be changed or developed.
我在做一个闹钟,等到谋个时间就开始执行谋个动作(在下面的案例里面简化为 print('ok'))。请问这是否是最佳办法?因为我担心会不会导致占用内存过高等问题。我看有一个叫 alarm 的库,也是用 while 循环等待时间。以下是我的示例代码:
在 2020 年 10 月 17 日 10 点 50 分 50 秒的时候触发事件 print('ok')
from datetime import datetime def alarm(): while True: now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") if now == '2020-10-17 10:50:50': print('ok') break if __name__ == '__main__': alarm() Supplement 1 Oct 17, 2020
感谢大家的回复!根据大家的建议和帮助,我决定采用计算时间差然后用sleep的办法。其他办法比如用第三方库或者线程等方法也很好,但我希望尽量简单点。这个只需要精确到未来某个时间的秒即可。我更新代码如下,希望对其他新手有帮助:
from time import sleep from datetime import datetime def alarm(): now = datetime.now().timestamp() set_time = datetime(2020, 10, 16, 22, 42, 50).timestamp() delta = set_time - now sleep(delta) print('ok') if __name__ == '__main__': alarm() 1 duyuyouci Oct 16, 2020 可以用 celery 做定时任务啊 |
2 ruanimal Oct 16, 2020 循环里加个 sleep 吧,不然 cpu 都占满了 |
3 nevin47 Oct 16, 2020 CPU 都炸了。。。。。。 |
4 RRRoger Oct 16, 2020 用操作系统的定时任务触发是不是会更好点 |
5 vZexc0m Oct 16, 2020 可以用 APScheduler |
6 yaoye555 Oct 16, 2020 crontab 或许更值得拥有 |
7 qile1 Oct 16, 2020 via Android 这样应该可以,但是有时候 print 有数据,程序确不执行挺奇怪,好像也没有啥好办法 |
8 ysc3839 Oct 16, 2020 内存占用不高,CPU 使用率会高。如果不想使用操作系统独有的 API 的话,那就加上 sleep 吧。 |
9 no1xsyzy Oct 16, 2020 占满一个核,内存不会泄漏 不要用等于判断时间 |
10 stephenxiaxy Oct 16, 2020 。。。 |
11 MoYi123 Oct 16, 2020 不如 asyncio.sleep |
12 MagnifierSun Oct 16, 2020 ??? 你知道这个语句一秒钟要执行多少遍吗哈哈哈 有个 Schedule 的库,自己去搜搜 |
13 Chenamy2017 Oct 16, 2020 加 sleep 即可,时间也不要用==,超过这个时间后就执行动作。 |
14 Sapp Oct 16, 2020 你这个时间必出坑... |
15 kimqcn Oct 16, 2020 谁把我的代码偷出来了呵呵呵 |
16 Vhc001 Oct 16, 2020 这是我见过最坑爹的代码 |
17 Chaidu Oct 16, 2020 建议转行 (狗头 |
18 Tokiomi Oct 16, 2020 哈哈哈,学生代码吧 |
19 sudoy OP |
20 est Oct 16, 2020 其实底层库就是你这样实现的。只不过加了很多东西。比如上面说的要加个 sleep(1) 这就是你最小定时精度。 |
23 widewing Oct 16, 2020 via Android sleep 为什么要加在循环里?直接 sleep 指定时间不香吗? |
24 dswyzx Oct 16, 2020 via iPhone 别听他们的,加 sleep 万一错过这个点了呢,大于等于时间万一没有拯救世界成功呢。 综上所述:能用就行! |
25 imdong Oct 16, 2020 之前有过类似的需求,不过我的做法是用 sleep 但是不是 sleep(1) 而是再执行完毕后,检查距离下一次执行的时间差,然后睡眠到那个时间。 |
26 momo1999 Oct 16, 2020 sleep(0)即可 |
28 sudoy OP @est 哈哈,虽然我找半天没有找到 python 内置的 `sleep()` 是怎么写的,你的话听起来还挺鼓励人的。不过他们说这样写会导致 CUP 占用过高,可能确实没有用 sleep 好,sleep 没有这么高的 CUP 占用。 |
29 wusheng0 Oct 16, 2020 via Android 是不是 fork 一个进程后台运行更好, 有没有大佬来说一下 |
30 felixcode PRO 多开几个闹钟就能把多核 CPU 占满了。 |
32 zkqiang Oct 16, 2020 没让你 sleep 0 啊。。直接计算 定时减去现在 有多少秒,sleep 多少秒就行了 |
34 zkqiang Oct 16, 2020 或者 sleep(0.5) 每半秒检查一次,另外时间不要用 == 判断,最好用区间判断允许一些误差 |
36 bruce00 Oct 16, 2020 狗头真的能保命 |
37 heyjei Oct 16, 2020 我真的在生产环境见过这样的代码,你们应该能够理解我当时的心情。 |
38 9LCRwvU14033RHJo Oct 16, 2020 sleep(0)真实绝了。 |
40 Norie Oct 16, 2020 via iPhone 这是 CPU 性能测试 |
41 fuchunliu Oct 16, 2020 via Android 你是对的,他要听他们的,不然别人说你跑的假程序,CPU 都没占用 |
42 ysc3839 Oct 16, 2020 @est Windows 有 SetThreadpoolTimer,这个可以设置绝对时间,不受睡眠影响,还可以设置允许系统推迟执行,相比 sleep 更加省电。 |
43 winglight2016 Oct 16, 2020 @heyjei 这样的生产环境还能有任何“生产”吗? |
44 Bijiabo Oct 16, 2020 看到 sleep(0) 笑死我了哈哈哈 |
45 lazyfighter Oct 16, 2020 既然 sleep,为什么不算一 sleep 多长时间呢 |
46 ThisQ Oct 16, 2020 用系统定时任务调用脚本执行呢? |
47 ysc3839 Oct 16, 2020 @wusheng0 我一般会选择用新线程来后台执行,fork 在某些操作系统上有坑,比如 Windows 没有 fork,macOS fork 之后不 exec 没法使用 CoreFoundation 。用线程的话可以共享资源,也没有那么多坑。 |
48 zgzb Oct 16, 2020 via Android 我选择 after |
49 nine9 Oct 16, 2020 可以考虑 threading.Event() event.wait(timeout=None) event.set() 也就是 APScheduler 这个库实现使用的 |
51 0bit Oct 16, 2020 sleep 的问题已经很多人说了,我提一下关于时间比对的问题吧。 现在这样用 str 比对,容易有小坑,还是应该用更本质的数据去比对,比如 unix timestamp,更不容易出错。 |
52 nuk Oct 16, 2020 最好调整成实时优先级,不然这一秒容易被跳过 |
54 DoctorCat Oct 16, 2020 兼容 posix 标准的系统还可以利用系统信号:signal 、setitimer 定时器交给 OS 去做了 |
55 ma7x Oct 16, 2020 win10 自带闹钟超级好用 为什么要造轮子 |
56 www5070504 Oct 16, 2020 你这种写法 每天多费半度电吧 加个 timer 之类的 sleep 都行啊 |
57 SmartKeyerror Oct 16, 2020 单线程直接用信号不就好了,向内核注册一个定时器,定时器到期后向进程发送 SIGALRM 信号。 |
58 darknoll Oct 16, 2020 传说中的忙等待自旋锁? |
59 fish267 Oct 16, 2020 还是 crontab 吧 |
60 muzuiget Oct 16, 2020 哈哈,我也想到传说中的自旋锁。 |
61 xionger Oct 16, 2020 哈哈 劝改行 |
62 ruanimal Oct 16, 2020 @findlisa 每时每刻都在判断时间是否相等,也就是 cpu 一直是忙碌的状态,自然就会占满一个核心。如果有 sleep,cpu 在你程序 sleep 的期间就干别的,或者休息去了。 ps: 去看看操作系统的书,看看进程的调度。 |
63 GoLand Oct 16, 2020 淦,这么精妙的代码我怎么想不到。 |
64 momo1999 Oct 16, 2020 哎哟,我错了,sleep 0 确实不行,起码得 0.001 |
65 kiracyan Oct 16, 2020 硬是要这么做建议你 sleep 个 300 秒 然后判断一下当前时间距离设定时间是不是小于 300 秒 再 sleep 1 秒 |
66 shenqi Oct 16, 2020 。。。明显的实习生写的代码。 (又不是不能用.jpg ) |
67 Hxu2M811KVSJqN75 Oct 16, 2020 这个算今日最佳 [欢乐贴] 么? |
68 jimmyismagic Oct 16, 2020 评论里说实习生写的代码的,自己可以写一个出来试试,看能做到多高的精度,要做到等于而不是大于等于 |
70 sapocaly Oct 16, 2020 |
71 iSecret Oct 16, 2020 用 crontab 执行任务的话没这么多蛋疼的事还可以顺道解决了可能需要重复执行的问题,非要用 py 建议 sleep(执行时间 - 当前时间)。 |
72 tabris17 Oct 16, 2020 实现了一个野生 spinning |
73 lane1 Oct 16, 2020 用术语来说, 你的写法是 spinlock, busy-waiting, CPU-bound... 不过话说计时器到底如何实现呢? |
74 Tonni Oct 16, 2020 哈哈,别的不说,楼主头像的狗子好可爱 |
75 UN2758 Oct 16, 2020 lz 这么狂野的写法,怀念当年的我,哈哈哈哈 |
76 JCZ2MkKb5S8ZX9pq Oct 16, 2020 直接算 timestamp 的时间差,sleep 一次到底不就好了。 这个格式化时间的操作有点多余,重复计算没必要啊。 |
77 wuwukai007 Oct 16, 2020 via Android 直接计算时间差,sleep,每次激活的时候重新计算, |
78 lysS Oct 16, 2020 想到见过 JS 延时函数: functionsleepSync(ms){ varcurr=newDate().getTime(); ms+=curr; while(curr<ms){ curr=newDate().getTime(); } } |
79 CSM Oct 16, 2020 via Android 直接一觉睡到目标时间,醒来后完成任务就行,循环也不用 |
80 echoick Oct 16, 2020 via iPhone 哈哈哈哈 sleep(0) |
81 inframe Oct 16, 2020 我真的在生产环境见过这样的代码,你们应该能够理解我当时的心情。 +1 |
82 ctro15547 Oct 16, 2020 延迟 0.1 秒就行 。。 |
83 E1n Oct 16, 2020 via Android 哈哈加油 |
84 Yinz Oct 17, 2020 不得不说,楼主心态蛮好的,加油,谁都有新手阶段,学习即可 |
85 by73 Oct 17, 2020 突然对 time.sleep 有了点兴趣,最后发现居然调用的是 select() 系统调用 |
86 irytu Oct 17, 2020 os.sched_yield() 不过 Windows 上没有这种方法 我一般为了 portable 会写成 time.sleep(0.0001) |
87 vcfghtyjc Oct 17, 2020 运行时候检测一下当前时间,然后算出需要的睡眠时间,sleep 就行了 |
88 shijingshijing Oct 17, 2020 sleep(0)没毛病,代码不改,在 crontab 里面设定 2020 年 10 月 17 日 10 点 50 分 50 秒执行一次就 ok 了。 |
89 discrete Oct 17, 2020 想起了 Sleep Sort. |
91 sudoy OP |
92 inorilzy Oct 17, 2020 APScheduler 和 celery 都可以定时任务。 |
96 flgn88 Oct 17, 2020 via iPhone 为何我想起了大名鼎鼎的“睡眠排序法”?! |
98 adamwong Oct 17, 2020 @SmartKeyerror 我怎么又抓到你了 |
99 nuk Oct 17, 2020 @sudoy import win32api,win32process,win32con pid = win32api.GetCurrentProcessId() handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, pid) win32process.SetPriorityClass(handle, win32process.REALTIME_PRIORITY_CLASS) |
100 IDAEngine Oct 17, 2020 via iPhone 用系统 API 不香吗? while sleep 不靠谱 |

