程序来不及处理消息该怎么办呢??有人建议可以直接丢弃,但这样行的通吗??(顶者有分)

Sco_field 2007-04-17 03:54:17
程序流程大概是这样的:

电脑PCI插槽上有一块定时计数器板卡,该计数器用来读取外部频率脉冲并定时产生溢出中断消息,现在外部过来的频率为1000Hz,即每秒钟定时计数器会接收到外部1000个脉冲.现在计数器设置为每读取10个脉冲就向我的MFC程序发送一个溢出中断消息,即此溢出中断消息每10ms就发送一次.
现在我是用一个单独的轮询线程不断的查询该溢出中断消息的.每当我的轮询线程捕获到此溢出中断消息时就开辟另一个仿真线程开始我的仿真程序.现在的问题是有时候,大约每产生5万~10万次左右的中断消息会有一个溢出中断消息我的仿真程序来不及处理,即轮询线程捕获到了中断消息,但我上一次的仿真程序仍在进行当中.
我现在是这样做呢,就是在仿真线程头尾加个线程锁,当中断消息来不及处理时就丢弃掉来不及处理的脉冲.但我觉的5万~10万次的中断消息就丢弃掉一个是不是丢弃的太频繁了呢?请问你们觉得多少次中断消息才可以丢弃一次呢?请问有这方面的教材吗?
放远到一般情况下,对于程序来不及处理的消息,你们是怎么做的呢?直接丢弃吗?
不知道我有没有讲清楚,先谢谢了啊
...全文
604 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
qingsion 2007-04-22
  • 打赏
  • 举报
回复
我来顶一个~~~
qingsion 2007-04-22
  • 打赏
  • 举报
回复
我来顶~~~
Sco_field 2007-04-22
  • 打赏
  • 举报
回复
大家不要谦虚啊,有意见尽管发飙啊~
晨星 2007-04-19
  • 打赏
  • 举报
回复
如果处理过程中涉及一些可能造成等待的IO操作,那么还是多线程比较好。
但为每个消息新建一个新的线程总归不太好,还是通过消息队列加线程池的方式比较好。
晨星 2007-04-19
  • 打赏
  • 举报
回复
可不可以将消息排队,然后一个一个地处理。
这样处理线程只需要一个。
qingsion 2007-04-19
  • 打赏
  • 举报
回复
好的.帮顶!^-^
小一郎 2007-04-19
  • 打赏
  • 举报
回复
看不懂,呵呵
weixlin 2007-04-18
  • 打赏
  • 举报
回复
看你的实时重要,还是消息更重要?
用一线程专门管理消息队列,另一线程来处理消息。
Sco_field 2007-04-18
  • 打赏
  • 举报
回复
谢谢以上各位朋友的热心回复!

对了. 如果一定是要每消息每线程, 我想你也应该考虑实现个线程池, 创建线程之类的操作, 也有不小代价
----------
是的啊,我编写的时候是每来一个线程就创建一个仿真线程,然后让仿真完成后仿真线程自己正常结束自己.然后下一次来中断消息时再创建再结束.确实有点花费啊.不过我不知道还有没有更好的方法.比如如果我只是一开始创建一个仿真线程,然后立即暂停该仿真线程.每当中断消息来的时候就启动它,完成时就又暂停它.不过这样好像有个问题,就是如何控制暂停的仿真线程继续从仿真函数头部开始执行而不是自己正常结束呢?
比如:
轮询线程A
{
if(中断消息B)
{
发送消息C
}
}
消息C处理函数D
{
if(仿真线程E处理完)
{
创建仿真线程E //每次创建仿真线程,花费代价较高
}
else
return;丢弃该次中断消息
}
仿真线程E
{
...
return;
}

但如果我一开始就创建个仿真线程:

初始化函数F:
{
创建仿真线程E;
暂停E;
}
轮询线程A
{
if(中断消息B)
{
发送消息C
}
}
消息C处理函数D
{
if(仿真线程E处理完)
{
继续下次仿真线程E,让其从函数头开始运行 //如何保证E能从头开始而不正常return结束 呢?困惑啊
}
else
return;丢弃该次中断消息
}

仿真线程E
{
...
return;
}

再次感谢楼上的各位!

liuyaoyou 2007-04-17
  • 打赏
  • 举报
回复
友情顶
晨星 2007-04-17
  • 打赏
  • 举报
回复
当然,我前面说的时指各种可能的办法都试过了之后。
如果你程序中有设计上的性能瓶颈,或者是其它的小bug,那最好不过了,修改一下设计或检查一下程序就搞定了。:P
zwlzwlzwl 2007-04-17
  • 打赏
  • 举报
回复
这种情况也只能提高硬件性能了吧,中段时间不能设大点吗
merlinfang 2007-04-17
  • 打赏
  • 举报
回复
可能要丢消息,系统有最大处理能力的,可以更客户谈谈
yutaooo 2007-04-17
  • 打赏
  • 举报
回复
哎, 多核时代到了, 我也没准备好啊. 加紧向 steedhorse(晨星) 这些老鸟学习!!
HewpKanXue 2007-04-17
  • 打赏
  • 举报
回复
提升软硬件处理能力。
看来多核位时代已提前到来了。
晨星 2007-04-17
  • 打赏
  • 举报
回复
即轮询线程捕获到了中断消息,但我上一次的仿真程序仍在进行当中
——如果这种效果因为可能累积而不敢进行缓冲,那就只能说客户的要求太高了,有点超出当前一定价格内的硬件处理能力了,搞不好也只能丢弃了。
yutaooo 2007-04-17
  • 打赏
  • 举报
回复
对了. 如果一定是要每消息每线程, 我想你也应该考虑实现个线程池, 创建线程之类的操作, 也有不小代价.
yutaooo 2007-04-17
  • 打赏
  • 举报
回复
我想我没问明确, 有点误解啊.

1.我认为轮训线程是必要的.

2.我迷惑的是仿真线程是否每条消息, 就开个新的线程?

3.问多CPU, 多核, 是在推测是是否存在大量线程调度, 现场切换引起的额外负荷. 没法做性能测试啊, 说不好, 不过你应该测试一下. 并且应该测试下高峰情况下会同时开多少个线程. 线程数量也是稀缺资源啊.

4.关于queue是这样的. 我基本上觉得你可以考虑将消息进一个单一队列, 另一个线程负责处理.这样只要总体算法不差, 性能过的去, 就不会造成队列益处. 可以解决瞬间的不及响应. 但这样的方案有待调查你两条消息间是否有数据依赖的问题.

5.同样, 我还建议你考虑一下用I/O Complete Port的方式. 这个比较罗嗦的, 可以参考下windows系统编程方面的书.
jixingzhong 2007-04-17
  • 打赏
  • 举报
回复
是否要丢弃,看你的需要......

既然明确是无法处理的,
那么丢弃可能也是必须的,
否则累积延迟更严重 ······
Sco_field 2007-04-17
  • 打赏
  • 举报
回复
先解释一下:
1 "可以不可以丢是由你的客户才能决定的","有需求决定"
----需求说明书上确实没有提到这个问题,但如果征询客户意见的话,答复我想肯定是100%的需要完全处理,绝对不能丢弃吧,谁都希望能获得最好的结果啊

2 "我不太理解。你这情况真的是需要每次都开一个新线程吗?WHY?"
-----首先,我想轮询线程是必要的吧,因为需要不断的捕获中断消息啊,另外仿真线程不必须吗?如果仿真程序放在轮询线程里,那么这个轮询线程就达不到"实时轮询"的目的了吧,因为这样的话,轮询线程捕获到中断消息之后就进行仿真处理了,哪有时间再来进行轮询呢?

3 "你是多CPU,多核的机器吗?实时性要求到底如何的?"
----单核的啊,实时性就是能确保每10ms发送来的消息都能仿真处理完.我就奇怪了,为什么绝大部分来的中断消息能够仿真处理完成,偏偏就有那么几个脉冲来不及仿真处理结束呢??我其他外部的程序可都没有运行的啊,一般是50万次的溢出中断消息总会有几个不能正常仿真结束,但这几个不能正常仿真结束的脉冲出现的时间是不固定的,有的时候在开始就出现了,有的时候在中间某个时候.

4 "如果10微秒还不能把中断处理完,我就认为大概你的设计大概很有问题"
-----我想解释一下,不是我的"中断消息处理时间"很长,而是当我接收到中断消息后(接收的过程应该很短),让程序进入到我创建的仿真线程,我制定的规则是如果这一次仿真线程没有运行完,则下一次轮询线程捕获到了中断消息后,由于仿真线程加了线程锁,程序就不会进入仿真线程了.此时我就丢弃了这个"没有处理完的"中断溢出消息.我所指的"没有处理完"这个消息实际上不是指没有捕获到这个消息,而是捕获到这个消息之后仿真线程没有正常结束掉.不知道我这样可解释清楚了呢?

谢谢各位了啊
加载更多回复(5)

65,213

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧