免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2796 | 回复: 5
打印 上一主题 下一主题

[C] 一个定时器问题,求解答 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-16 15:47 |只看该作者 |倒序浏览
最近在使用pjlib,它的定时器原理是单独一个线程在轮询定时器任务链表,发现有任务到时间了就会调用该任务的回调函数。
在调用回调函数之前 ,它会释放掉定时器相关的锁。
如果有一个这样的情境,我要cancel一个定时器,但是刚好这个定时器到时间了并且进入了回调函数。主线程调用了cancel timer,我认为定时器被取消了,定时器的相关事务理所当然不会再执行。但是因为这个线程同步问题,使程序出现很多错误。
我就有一个疑惑,设计定时器的人是不是认为这种安全性问题就应当是上层程序员要考虑的?我看了一下java util里定时器的实现,也是这样。
但是作为上层程序员来说这是多么操蛋的事,我取消一个定时器还要考虑这个定时器可能同时会触发。

大神们怎么看待这个问题

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
2 [报告]
发表于 2013-12-16 17:22 |只看该作者
你可以只设置一个取消标志,让定时器自己检查这个标志来取消自己——一般来说,这个标志会在定时器执行核心逻辑前检查一次;如果执行中被设置了,那么相关定时器就在下次被调度时进入撤销逻辑。

论坛徽章:
0
3 [报告]
发表于 2013-12-16 17:33 |只看该作者
问题就出在这里了,定时器逻辑核心检查这个标志的时候主线程还没有调用cancel。检查完了,释放锁,这下子cancel被调用了,timer线程正在进入callback的入口 。回复 2# shan_ghost


   

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
4 [报告]
发表于 2013-12-17 10:28 |只看该作者
本帖最后由 shan_ghost 于 2013-12-17 10:29 编辑
nichelnich 发表于 2013-12-16 17:33
问题就出在这里了,定时器逻辑核心检查这个标志的时候主线程还没有调用cancel。检查完了,释放锁,这下子ca ...


问题没出在这里。

人家定时器的标志是定时器的,你自己的是自己的。混用你还想有好下场?

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
5 [报告]
发表于 2013-12-17 11:08 |只看该作者
1、不要去搞大而全,也不要预期别人会给你搞大而全
比如,定时器就是个定时器:人家只管到时间通知你,别的人家可不管,也不应该管:一个在你做任何事时都喋喋不休的反复问“你确定xxx吗”的保姆是很讨厌的。

2、明确语义,不要窥探别人的内部实现,更不要改变别人内部实现的语义
比如,java认为你应该这样取消一个定时器线程:
http://stackoverflow.com/questio ... a-running-timertask

注意,这里cancel的语义是:停止执行尚未执行的任务,但不触及那些已经在执行中的任务——正处于“保护现场,准备进入run函数状态”的任务也是正在执行的任务。

至于定时器内部的锁,那是为了保证在多线程访问timer时,timer内部的数据结构不被破坏用的。

3、保证定时器线程和主线程之间的执行逻辑正确是你的责任,定时器没法替你管。
比如,照你的想法,你觉得自己调用cancel后,定时器是应该在cancel里面terminate你尚未执行完的任务呢、还是卡死在调用点等你的任务自己退出?万一你的任务不会在短时间内退出呢?这种实现不是扯淡吗?谁敢把定时器写成这样?

进一步说,既然是“线程”,那就说明它和其它线程之间的执行次序本身就是不确定的。你必须实现一个同步点才能保证它们按某种次序执行。事先预料到、并正确实现这个同步点是你的责任,别推给别人。

论坛徽章:
0
6 [报告]
发表于 2013-12-17 14:07 |只看该作者
回复 5# shan_ghost
我就是看看更多人的想法,谢谢,这是我第一次上chinaunix。感谢shan_ghost
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP