• lv6 嵌入式开发-Flappy bird项目(信号机制、定时器功能实现)


    目录

    1 信号(signal)

    2 设置信号响应方式 – signal

    3 设置定时器

    4 示例


    问题:

    getch()阻塞获取键盘按键输入, 怎么操作才能不影响小鸟下落和管道移动?

    getch如果阻塞,下面的程序都是无法执行。通过信号机制方式实现。

    1 信号(signal)

    在Linux中,软中断信号(signal,简称为信号)是在软件层次上对中断的一种模拟,用来通知进程发生了异步事件。内核可以因为内部事件而给进程发送信号,通知进程发生了某个事件。

    信号响应的方式:

    1.忽略信号,即对信号不做任何处理;

    2.捕捉信号,即信号发生时执行用户自定义的信号处理函数。

    3.执行缺省操作,Linux对每种信号都规定了默认操作。

    信号的检测与处理流程图

    2 设置信号响应方式 – signal

    1. #include
    2. #include
    3. typedef void (*sighandler_t)(int);
    4. sighandler_t signal(int signum, sighandler_t handler);

    成功时返回原先的信号处理函数,失败时返回SIG_ERR  

    signum:指明了所要处理的信号类型  

    handler:描述了与信号关联的动作               

            SIG_DFL代表缺省方式; SIG_IGN 代表忽略信号;               

            指定的信号处理函数代表捕捉方式

    示例

    1. // 头文件省略
    2. void handler (int signo) {
    3. printf(“HELLO!\n”);
    4. }
    5. int main() {
    6. signal(SIGINT, handler);
    7. while ( 1 ) ;
    8. return 0;
    9. }

    3 设置定时器

    1. struct itimerval {
    2. struct timeval it_interval; /* 计时器重新启动的间歇值 */
    3. struct timeval it_value; /* 计时器安装后首次启动的初 }; 始值,之后就没有用 */
    4. struct timeval {
    5. long tv_sec; /**/
    6. long tv_usec; /* 微妙*/
    7. };

    计时器的实现

    1. int setitimer(int which, const struct itimerval *value,
    2. struct itimerval *ovalue)

    参数: which:间歇计时器类型,    

                       ITIMER_REAL     //数值为0,发送的信号是SIGALRM。

                struct itimerval *value:将value指向的结构体设为计时器的当前值,

                struct itimerval *ovalue:保存计时器原有值。一般设置为NULL。

    返回值: 成功返回0。失败返回-1。

    4 示例

    1. #include
    2. #include
    3. #include
    4. #include
    5. int x=10,y=10;
    6. int a=5,b=10;
    7. void handler(int sig)
    8. {
    9. move(a,b);
    10. addch('B');
    11. refresh();
    12. b++;
    13. }
    14. int main(int argc, const char *argv[])
    15. {
    16. char ch;
    17. initscr();//进入curses模式
    18. curs_set(0);
    19. noecho();//禁止字符显示
    20. keypad(stdscr,1);//允许使用功能键
    21. start_color();//启动颜色机制
    22. init_pair(1,COLOR_WHITE, COLOR_RED);
    23. init_pair(2,COLOR_GREEN,COLOR_WHITE);
    24. signal(SIGALRM, handler);
    25. /*设置定时时间*/
    26. struct itimerval timer;
    27. timer.it_value.tv_sec = 3;//首次启动定时时间
    28. timer.it_value.tv_usec = 0;
    29. timer.it_interval.tv_sec = 1;//之后每次的定时时间
    30. timer.it_interval.tv_usec = 0;
    31. /*启动定时*/
    32. setitimer(ITIMER_REAL, &timer, NULL);
    33. while(1){
    34. ch = getch();
    35. if(ch == 'Q')
    36. {
    37. attron(COLOR_PAIR(1));
    38. move(x,y);
    39. addch('A');
    40. refresh();
    41. y++;
    42. attroff(COLOR_PAIR(1));
    43. }
    44. }
    45. while(1);
    46. endwin();//退出curses模式
    47. return 0;
    48. }

    5 练习

    使用信号机制实现每隔1s打印字符串“Flappy bird”,提交代码。

    方式1

    1. #include
    2. #include
    3. #include
    4. #include
    5. void handle(int sig)
    6. {
    7. printf("Flappy bird\n");
    8. }
    9. int main(int argc,char *argv[])
    10. {
    11. struct sigaction act;
    12. struct itimerval timevalue;
    13. int ret;
    14. act.sa_handler = handle;
    15. act.sa_flags = 0;
    16. sigemptyset(&act.sa_mask);
    17. timevalue.it_interval.tv_sec = 1;
    18. timevalue.it_interval.tv_usec = 0;
    19. timevalue.it_value.tv_sec = 5;
    20. timevalue.it_value.tv_usec = 0;
    21. setitimer(ITIMER_REAL, &timevalue,NULL);
    22. ret = sigaction(SIGALRM,&act,NULL);
    23. if(ret < 0)
    24. {
    25. perror("sigaction");
    26. return 0;
    27. }
    28. while(1)
    29. {
    30. }
    31. return 0;
    32. }

    方式2

    1. #include
    2. #include
    3. #include
    4. #include
    5. void handle(int sig)
    6. {
    7. printf("Flappy bird\n");
    8. }
    9. int main(int argc,char *argv[])
    10. {
    11. struct itimerval timevalue;
    12. timevalue.it_interval.tv_sec = 1;
    13. timevalue.it_interval.tv_usec = 0;
    14. timevalue.it_value.tv_sec = 5;
    15. timevalue.it_value.tv_usec = 0;
    16. setitimer(ITIMER_REAL, &timevalue,NULL);
    17. signal(SIGALRM,handle);
    18. while(1)
    19. {
    20. }
    21. return 0;
    22. }

  • 相关阅读:
    Node.js之http模块
    【老生谈算法】matlab实现Kmeans聚类算法源码——Kmeans聚类算法
    My Forty-Third Page - 二叉搜索树中的插入操作 - By Nicolas
    E - Fire! (双向bfs)
    Leetcode.4 寻找两个正序数组的中位数
    @设计模式-代理模式
    SSM框架原理【超级详细】
    mac 查看本机 ip
    SpringBoot+Session 实现接口验证(过滤器+拦截器)
    vue-admin-template改变接口地址
  • 原文地址:https://blog.csdn.net/m0_60718520/article/details/133491872