电子产业一站式赋能平台

PCB联盟网

搜索
查看: 177|回复: 0
收起左侧

嵌入式应用软件经常用到的延时函数,有些还有副作用!

[复制链接]

561

主题

561

帖子

3989

积分

四级会员

Rank: 4

积分
3989
发表于 2025-2-14 17:50:00 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师关注我,一起变得更加优秀!
/ b% E1 O0 U" h& f! c( x嵌入式软件开发过程中,基本都会用到“延时”,本文分享几种Qt种延时处理方法。
2 c+ r; Z- W( r0 x  h5 f一、阻塞型延时/ M! W2 L- S' z  |$ ~; G- ^2 z
阻塞的原理就是:在延时期间,本线程的事件循环得不到执行。# m# I, U- {0 j  a9 f. X1 e! v
1、QThread类的sleep()最简单的延时方法就是使用QThread类的sleep(n)、msleep(n)、usleep(n),这几个函数的不良后果就是,GUI会在延时的时间段内失去响应,界面卡死,所以,这三个函数一般用在非GUI线程中。
1 H( u7 U/ o9 z7 d0 {5 r& QQThread::msleep(50);//阻塞延时50ms2 W! S4 `. W% ^5 J" ~8 w% q
2、使用定时器:死等void Delay_MSec_Suspend(unsigned int msec)
/ ~8 E  k4 }5 v3 @' e1 u7 H$ ]{   
- v) k5 k! z7 ]8 \    QTime _Timer = QTime::currentTime().addMSecs(msec);5 x% V4 W5 x4 W) j- C1 J
    while( QTime::currentTime() 二、非阻塞延时原理无非就是利用事件循环,有两种原理:& D/ Y- }; @* G8 \8 k& e' B
1、处理本线程的事件循环在等待中,不断强制进入当前线程的事件循环,这样可以把堵塞的事件都处理掉,从而避免程序卡死' E+ m6 `% M2 A# F3 F7 p
void Delay_MSec(unsigned int msec)5 }, H+ u/ S; c) X+ b. q
{2 F8 b: }" T& C
    QTime _Timer = QTime::currentTime().addMSecs(msec);
5 h& |" G5 }! {$ ]  ~' @( P( _    while( QTime::currentTime() 2、使用子事件循环创建子事件循环,在子事件循环中,父事件循环仍然是可以执行的# d2 f- B) D' b3 b$ w3 }' z) M
void Delay_MSec(unsigned int msec), v  \2 K. }) W# z0 j) y
{, W0 F& Z' d* L' |
    QEventLoop loop;//定义一个新的事件循环; ^; y; d  X7 g
    QTimer::singleShot(msec, &loop, SLOT(quit()));//创建单次定时器,槽函数为事件循环的退出函数7 c1 ?! v* X: u2 v7 ~) H
    loop.exec();//事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出
8 f9 U: o9 b; `1 p9 `3 l2 X" j}) ^# w: l. O5 t
三、耗时代码的处理假设有这样的应用情景:点击某个button之后,需要读入并处理一幅图像,需要耗时20秒才能处理完。
1 ^/ w7 g" h' l0 }$ H在这20s内,GUI会失去效应,界面上的任何元素都无法被点击,这种情况应该怎么办?方法有两种:1、用另一个线程去处理这个耗时任务;2、在耗时任务中,不断地去处理本线程的事件循环,以保证GUI的及时响应。
% g: U8 b8 E* l; W, r! }% bfor(i=0; i for(j=0; j 一般来说,processEvents()不宜被调用的过于频繁,也不宜被调用的不够频繁,过于频繁的话,一方面会使线程的响应更好,但另一方面会导致原本就耗时的任务变得更加耗时;
+ I. @/ }. P) a0 L& s2 D不够频繁的话,显然可能会使GUI线程的响应变差,例如每500ms才被调用一次,那么GUI的事件循环就只能500ms才被处理一次,
. f8 A+ g& X% R7 B2 M当然,这个问题可以通过设定processEvents()的第二个形参略微得到缓解,更好的做法是,保证被调的周期
" N! v  t/ n  }* _0 v副作用:(特别注意!)( @2 ~3 U# m- l! k
1、在点击按钮之后,这个20s的耗时任务开始执行,尚未执行完毕时,我们点击了GUI的关闭按钮,那么GUI会立即消失,但是这个耗时任务仍然会在后台执行,直到执行完毕,进程才会退出。解决办法:重写关闭事件,在关闭事件的函数中直接结束进程。2 ]" n& G  w' ?% ^6 y! g  J
2、在点击按钮之后,这个20s的耗时任务开始执行,执行到第5秒时,我们再次点击了这个按钮,那么QT又会执行一个新的20s任务,这个新任务完成后,又会接着把第一个20s任务从上次被打断的第5秒继续执行。如果这个任务是可重入的,后果仅仅是被执行了两遍,如果任务不可重入,那情况就彻底糟糕了。解决办法:点击按钮后把这个按钮disable掉,执行完再enable。
5 A  x4 \% v( h7 Q1 J来源地址:- K8 C2 v) k: A2 R8 a, j4 {
https://blog.csdn.net/qq_31073871/article/details/80472347
-END-
, ^1 A2 t/ f1 Q5 r往期推荐:点击图片即可跳转阅读
- r/ i: a' w: A5 d% D' c7 J$ w7 P! B                                                        1 ~/ M4 v, f, y$ L
                                                                9 U% S( A* k% {; r
                                                                       
- U+ ]* g6 V/ c" i1 n" i                                                                               
# m& ~( H7 t$ D9 v

pfuhryogd136406127725.jpg

pfuhryogd136406127725.jpg
1 T% F0 X4 D+ l* H# O
                                                                               
8 J5 r2 E% ^' m/ X+ _* r                                                                                        嵌入式软件工程师,被深夜的硬件调试击碎了傲慢。
( j' b7 S# Y4 k                                                       
6 [& O! Y$ f3 X4 N                                                               
4 p* S, U$ Q+ T# F2 u1 f& [                                                                        7 }7 w, s( M! |2 U
                                                                               
" x* g& n5 _2 P6 F( \8 U

ptw2vfzkwwa6406127825.jpg

ptw2vfzkwwa6406127825.jpg

, y$ |% E! P: S                                                                                ' x$ m1 g% h5 r3 `
                                                                                        把 DeepSeek-R1 大模型部署到RK3588开发板上,看看运行情况如何?, `5 ]5 L4 i+ v3 S
                                                                ! o& ?) F# ?% F5 B
                                                                        " e8 g+ I, n! }3 ]: F* R5 I
                                                                               
4 ~) c' t7 ]' o! d: W+ @5 h

nwcysosucrb6406127926.jpg

nwcysosucrb6406127926.jpg

. N7 _$ o0 M7 v. z4 t& G% b+ t                                                                                5 @9 O0 V8 m& ?1 T3 U
                                                                                        不久的将来,Rust 会成为主流的嵌入式软件编程语言吗?& J" X% L4 Q: j* y% ~9 ^+ }
                                                                               
! ~" D9 T- P0 \  C; N* P                                                                        % y1 B$ N+ x9 U% Z! p
                                                               
5 j; I; H( m% l: r                                                        我是老温,一名热爱学习的嵌入式工程师
* }. N  K" i4 |9 x3 P关注我,一起变得更加优秀!
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表